React 中 keys 的作用是什么?
用于追踪哪些列表中元素被修改,添加,移除的辅助标识,减少不必要的渲染
调用 setState 之后发生了什么?
- react 将传入的参数与组件当前的状态合并调和
- 根据新的状态构建react元素数并且重新渲染UI界面
- 在react得到元素树后会自动计算与之前的差异然后根据差异最小化重新渲染
react生命周期
- 初始化阶段
getDefaultProp:获取实例默认属性
getInitialState:获取每个实例的初始化状态
componentWillMount: 组件即将被装载渲染到页面上
render:生成虚拟DOM节点
componentDidMount:组件真正被装载 - 运行中
componentWillReceiveProps:组件将要收到属性时调用
shouldComponentUpdate: 组件在接受新的状态或新属性时调用可以return false 阻止render更新
componentWillUpdate:组件即将跟新不能修改属性和状态
render:组件重绘 - 销毁阶段
componentWillUnmount:组件即将被销毁
为什么虚拟DOM可以提高性能
虚拟DOM其实是在js和DOM之间加了一层缓存,利用dom diff算法避免没必要的dom操作,可以只更新变化的那部分视图
react diff算法原理
- 把树形结构按层级分解,只比较同级元素
- 给列表结构的每个单元添加唯一的key,方便比较
- react只会匹配相同class的组件
- 合并操作,调用setstate,react重新渲染对应部分视图
react构建组件的方式
- react.createClass()
- es6 class
- 无状态函数
react工作原理
react 会创建虚拟DOM当组件中状态发生改变的时候会通过reacr diff算法标记虚拟DOM中的变化,调节更新DOM
React 中 Element 与 Component 的区别
element:所见内容的数据结构,对UI的描述,是通过jsx构建的声明式代码片段
component: 接收参数输入返回某个react element的函数或者类
类组件(Class component)和函数式组件(Functional component)
Class component:可以使用额外的功能,例如生命周期,组件自身状态
Functional component: 仅仅是接受props,并渲染到页面也成为无状态组件
react事件处理逻辑
为解决浏览器兼容性问题,react将浏览器原生事件都封装成合成事件,传入设置的事件中,组合事件提供了和原生事件相同的接口不仅屏蔽了底层浏览器的差异性还保证了行为的一致性,react以单一事件监听的方式将所有的事件都发送到顶层做处理,这样React 在更新 DOM 的时候就不需要考虑如何去处理附着在 DOM 上的事件监听器,最终达到优化性能的目的。
refs
refs其实是访问DOM元素或组件实例是安全门,refs的值其实是一个回调函数,接受底层DOM元素或者被挂载的组件实例作为它的第一实例
(在构造函数中)调用 super(props) 的目的是什么
在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props。
状态(state)和属性(props)之间有何不同
- State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
- props 由父组件传递给子组件,并且就子组件而言,props 是不可变的。组件不能改变自身的 props
受控组件和非受控组件
- 受控组件:包含表单元素的组件将会在 state 中追踪输入的值,并且每次调用回调函数时,如 onChange 会更新 state,确保数据来源的单一
- 非受控组件:不需要设置它的state属性,而通过ref来操作真实的DOM。
为什么建议传递给 setState 的参数是一个 callback 而不是一个对象
props和state 的更新可能是异步的,不能依赖他们的值去计算下一个state
展示组件(Presentational component)和容器组件(Container component)之间有何不同
- 展示组件关心组件看起来是什么。展示专门通过 props 接受数据和回调,并且几乎不会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心 UI 状态而不是数据的状态。
- 容器组件则更关心组件是如何运作的。容器组件会为展示组件或者其它容器组件提供数据和行为(behavior),它们会调用 Flux actions,并将其作为回调提供给展示组件。容器组件经常是有状态的,因为它们是(其它组件的)数据源。
何为 JSX
JSX 是 JavaScript 语法的一种语法扩展,并拥有 JavaScript 的全部功能。JSX 生产 React "元素",你可以将任何的 JavaScript 表达式封装在花括号里,然后将其嵌入到 JSX 中。在编译完成之后,JSX 表达式就变成了常规的 JavaScript 对象,这意味着你可以在 if 语句和 for 循环内部使用 JSX,将它赋值给变量,接受它作为参数,并从函数中返回它。
为什么 JSX 中的组件名要以大写字母开头
小写字母开头: 内置组件,HTML 元素,例如 <div>,<span>,会编译成 React.createElement('div')。
大写字母开头:自定义组件或 JS 文件中导入的组件,例如 <Foo />,会编译成 React.createElement(Foo)。
JSX 语法依赖babel进行解析
小写字母开头的 tagName 直接转为 string 字符串;
JSX 中使用点语法时,不管是大写还是小写,最终都会解析成对象和属性,而不是字符串,也所以虽然 C[p] 和 C.p 一样,但是 JSX 中 <c.p /> 可以解析而 <c[p] /> 不行。