1. 当你调用setState
的时候,发生了什么事?
将传递给setState
的对象合并
到组件的当前状态
,这将启动一个和解
的过程,构建一个新的react
元素树,与上一个元素树进行对比(diff)
,从而进行最小化
的重渲染
2.React
项目用过什么脚手架
creat-react-app
Yeoman
3. 什么时候用类组件Class Component,
或函数组件Functi
如果您的组件具有状态
(state)
或生命周期
方法,请使用Class
组件。否则,使用功能组件
4.React
中keys
的作用是什么?
Keys
是React
用于追踪哪些列表中元素被修改
、被添加
或者被移除
的辅助标识
render () {
return (
‹ul›
{this.state.todoItems.map(({item, key}) =› {
return ‹li key={key}›{item}‹/li›
})}
‹/ul›
)
}
在开发过程中,我们需要保证某个元素的key
在其同级元素中具有唯一性
。在React Diff
算法中React
会借助元素的Key
值来判断该元素是新近创建
的还是被移动
而来的元素,从而减少不必要的元素重渲染
。此外,React
还需要借助Key
值来判断元素与本地状态的关联关系
,因此我们绝不可忽视转换函数中Key
的重要性
5.React
优势
-
React
速度很快:它并不直接对DOM
进行操作,引入了一个叫做虚拟DOM
的概念,安插在javascript
逻辑和实际的DOM
之间,性能好。
-
- 跨浏览器兼容:虚拟
DOM
帮助我们解决了跨浏览器问题,它为我们提供了标准化的API
,甚至在IE8
中都是没问题的。
- 跨浏览器兼容:虚拟
- 一切都是
component
:代码更加模块化
,重用代码
更容易,可维护性
高。
- 一切都是
- 单向数据流:
Flux
是一个用于在JavaScript
应用中创建单向数据层的架构
,它随着React
视图库的开发而被Facebook
概念化。
- 单向数据流:
- 同构纯粹的
javascript
:因为搜索引擎
的爬虫程序依赖的是服务端响应
而不是JavaScript
的执行,预渲染你的应用有助于搜索引擎优化
- 同构纯粹的
- 兼容性好:比如使用
RequireJS
来加载和打包,而Browserify
和Webpack
适用于构建大型应用
- 兼容性好:比如使用
6.react diff
原理
-
把树形结构按照
层级分解
,只比较同级元素
-
给列表结构的每个单元添加
唯一
的key
属性,方便比较 -
React
只会匹配相同class
的component
(这里面的class
指的是组件的名字)合并操作,调用component
的setState
方法的时候,React
将其标记为dirty
到每一个事件循环结束,React
检查所有标记dirty
的component
重新绘制选择性
子树渲染。开发人员可以重写shouldComponentUpdate
提高diff
的性能。
7. react
生命周期函数
- 初始化阶段:
getDefaultProps
//获取实例的默认属性
getInitialState
//获取每个实例的初始化状态
componentWillMount
//组件即将被装载、渲染到页面上
render
//组件在这里生成虚拟的 DOM 节点
componentDidMount
//组件真正在被装载之后
- 运行中状态:
componentWillReceiveProps
//组件将要接收到属性的时候调用
shouldComponentUpdate
//组件接受到新属性或者新状态的时候(可以返回 false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行)
componentWillUpdate
//组件即将更新不能修改属性和状态
render
//组件重新描绘
componentDidUpdate
//组件已经更新
- 销毁阶段:
componentWillUnmount
//组件即将销毁
8.shouldComponentUpdate
是做什么的?
shouldComponentUpdate
这个方法用来判断是否需要调用render
方法重绘dom
,因为dom的描绘
非常消耗性能,如果我们能在shouldComponentUpdate
方法中能够写出更优化的dom diff
算法,可以极大的提高性能
9. 为什么虚拟dom
会提高性能?
-
虚拟dom
相当于在js
和真实dom
中间加了一个缓存,利用dom diff
算法避免了没有必要的dom
操作,从而提高性能
- 用
JavaScript对象
结构表示dom树
的结构,然后用这个树构建一个真正的dom树
插到文档当中当状态变更
的时候,重新构造一棵新的对象树
。然后用新
的树和旧
的树进行比较
,记录两棵树差异
并把所记录的差异应用到真正的dom树
上,视图就更新
了
10.React
中refs
的作用是什么?
Refs
是React
提供给我们的安全访问DOM
元素或者某个组件实例的句柄,我们可以为元素添加ref
属性然后在回调函数中接受该元素在DOM
树中的句柄,该值会作为回调函数的第一个参数返回:
class CustomForm extends Component {
handleSubmit = () =› {
console.log('Input Value: ', this.input.value);
};
render() {
return (
‹form onSubmit={this.handleSubmit}›
‹input type='text' ref={input =› (this.input = input)} /›
‹button type='submit'›Submit‹/button›
‹/form›
);
}
}
上述代码中的input
域包含了一个ref
属性,该属性声明的回调函数
会接收input
对应的DOM
元素,我们将其绑定到this
指针以便在其他的类函数中使用。
另外值得一提的是,refs
并不是类组件
的专属,函数式组件同样能够利用闭包
暂存其值:
function CustomForm({ handleSubmit }) {
let inputElement;
return (
‹form onSubmit={() =› handleSubmit(inputElement.value)}›
‹input type='text' ref={input =› (inputElement = input)} /›
‹button type='submit'›Submit‹/button›
‹/form›
);
}
11.setState
和replaceState
的区别
-
setState
是修改其中的部分状态
,相当于Object.assign
,只是覆盖,不会减少原来的状态 -
replaceState
是完全替换
原来的状态,相当于赋值
,将原来的state
替换为另一个对象,如果新状态属性
减少,那么state
中就没有这个状态了
12.React`中有三种构建组件的方式
React.createClass()
、ES6 class
和无状态函数
13.描述事件在React
中的处理方式
-
为了解决跨浏览器兼容性问题,
React
中的事件处理程序将传递SyntheticEvent
的实例,它是React
的浏览器本机事件的跨浏览器包装器
-
这些
SyntheticEvent
与原生事件具有相同的接口
,除了它们在所有浏览器
中都兼容 -
React
实际上并没有将事件
附加到子节点
本身 -
React
将使用单个事件监听器监听顶层的所有事件
-
这对于性能是有好处的,这也意味着在更新
DOM
时,React
不需要担心跟踪事件监听器
14.应该在React
组件的何处发起Ajax
请求
-
在
React
组件中,应该在componentDidMount
中发起网络请求,这个方法会在组件第一次挂载
(被添加到DOM
)时执行,在组件的生命周期中仅会执行一次
-
如果在组件挂载之前
Ajax
请求已经完成,那么就是尝试在一个未挂载的组件上调用setState
,这将不起作用。 -
在
componentDidMount
中发起网络请求将保证这有一个组件可以更新
了。
15. 调用super(props)
的目的是什么
-
在
super()
被调用之前,子类是不能使用this
的,在ES2015
中,子类必须在constructor
中调用super()
-
传递
props
给super()
的原因则是便于(在子类中)能在constructor
访问this.props
16.除了在构造函数中绑定this
,还有其它方式吗
-
用属性
初始值设定项
(property initializers)来正确绑定回调
,create-react-app
也是默认支持的 -
箭头函数,但问题是每次
组件渲染
时都会创建一个新的回调
17.为什么setState的参数是一个
callback`而不是一个对
因为
this.props
和this.state
的更新可能是异步
的,不能依赖它们的值去计算下一个state
18.在React
当中Element
和Component
有何区别?
-
React Element
是描述屏幕上所见内容的数据结构,是对于UI
的对象表述 -
典型的
React Element
就是利用JSX
构建的声明式代码片然后被转化为createElement
的调用组合 -
React Component
是一个函数
或一个类
,可以接收参数
输入,并且返回某个React Element
19.状态(state)和属性(props)之间有何区别
-
State
是一种数据结构,用于组件挂载时所需数据的默认值 -
State
可能会随着时间的推移
而发生突变,但多数时候是作为用户事件行为
的结果 -
Props
(properties的简写)则是组件的配置
。props
由父组件
传递给子组件
,并且就子组件
而言,props
是不可变的(immutable) -
组件
不能改变自身的props
,但是可以把其子组件的props
放在一起(统一管理)Props
也不仅仅是数据回调函数
,也可以通过props
传递
20.createElement
和cloneElement
有什么区别?
- 传入的第一个参数不同
React.createElement()
:JSX语法
就是用React.createElement()
来构建React
元素
它接受三个参数:
- 第一个参数可以是一个标签名。
如div
、span
,或者React
组件。 - 第二个参数为传入的属性
- 第三个以及之后的参数,皆作为组件的子组件。
React.createElement(type,`[props],`[...children]);
-
React.cloneElement()
与React.createElement()
相似,不同的是它传入的第一个参数是一个React
元素,而不是标签名
或组件
;新添加的属性
会并入原有的属性
,传入到返回的新元素
中,而旧的子元素将被替换
,将保留原始元素
的键
和引用
React.cloneElement(element,`[props],`[...children]);
网友评论