大家好,欢迎来到IT知识分享网。
React面试题整理
1、react的生命周期
1)、生命周期是什么?
react 实例的生命周期,就是react实例从初始化,更新,到销毁的过程
2)、react实例生命周期经历三个阶段
初始化阶段:完成从react组件创建到首次渲染的过程
更新阶段:当调用setState函数时,会引起组件的重新渲染
销毁阶段:完成组件的销毁
3)、三个阶段分别对应的构造函数有:
- 初始化阶段:
constructor
构造函数里,可以做状态的初始化,接收props的传值
componentWillMount: 在渲染前调用,相当于vue中的beforeMount
render
渲染函数,不要在这里修改数据。 vue中也有render函数。
componentDidMount
渲染完毕,在第一次渲染后调用。
- 运行中阶段(更新)
当组件的 props 或 state 发生变化时会触发更新(严谨的说,是只要调用了setState()或者改变了props时)。组件更新的生命周期调用顺序如下:
shouldComponentUpdate
是否更新? 需要返回true或者false。如果是false,那么组件就不会继续更新了。
componentWillUpdate,
即将更新。
componentWillReceiveProps(nextProps): 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。nextProps 是props的新值,而 this.props是旧值。
render
不要在这里修改数据
componentDidUpdate
在组件完成更新后立即调用。在初始化时不会被调用。 相当于vue中的updated
- 销毁阶段(卸载)
componentWillUnmount()
即将卸载,可以做一些组件相关的清理工作,例如取消计时器、网络请求等
2、为什么虚拟DOM 会提高性能
首先,(虚拟DOM是什么) 虚拟DOM就是一个JavaScript对象。通过这个JavaScript对象来描述真实DOM
如:
{
tagName:"p",
style:"width:200px;height: 100px;",
innerHTML:"我是p"
},
其次,操作虚拟DOM,就是在操作javascript对象,所以,并不会引起页面的重绘和重排。而操作真实DOM是会引起页面的重绘和重排的。
https://blog.csdn.net/jiang7701037/article/details/98516468 (页面的重排和回流)
3、React的diff原理
-
传统diff算法
需要遍历整棵树的节点然后进行比较,是一个深度递归的过程,运算复杂度常常是O(n^3) -
react diff的优化策略
-
DOM节点跨层级的操作不做优化,因为很少这么做,这是针对的tree层级的策略;
-
对于同一个类的组件,会生成相似的树形结构,对于不同类的组件,生成不同的树形结构,这是针对conponent层级的策略;
-
对于同一级的子节点,拥有同层唯一的key值,来做删除、插入、移动的操作,这是针对element层级的策略;
4、调用setState之后,发生了什么?
1)、合并state
把传入setState()里的参数对象和当前的state进行(属性)合并。 触发调和过程(Reconciliation)
2)、 重新渲染组件
2.1) React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
2.2) React 会自动计算出新的树与老树的节点差异(用diff算法),然后根据差异对界面进行最小化重渲染
5、state和props的区别
1)、state是组件的状态,也叫组件内部的数据
2)、props是组件的属性,也可以认为是外部给组件传入的数据
6、在构造函数里调用super函数并把props作为参数传入的作用是啥?
1)、在构造函数里调用super的目的是:保证子类(组件里)有this;
在ES6中,super()函数就是父类的构造函数。所以,在react里定义类组件时,调用super就是在调用React.Component的构造函数。
2)、调用super函数时,把props传入的目的是,保证this有属性props;即:在子类(组件)里能够使用this.props。
即: 执行 super(props) 是为了让 React.Component 初始化 this.props。
React.Component类内部写法:
class Component {
constructor(props) {
this.props = props;
}
}
3)、补充解释:
看代码(很奇怪的现象):
class Home extends React.Component{
constructor(props){
super();//此处没有props
}
render(){
return (
{/*下面竟然可以拿到 this.props*/}
<div>{this.props.name}</div>
)
}
}
ReactDOM.render(<Home name="hi"/>,document.getElementById("box"))
为什么会出现以上情况?
因为,React组件(如:上面的Home组件)在实例化时, 会设置一遍 props 。所以,没有问题喽。
那,那,那……??@#¥……&!*…… 天哪?
再看:
class Home extends React.Component{
constructor(props){
super();//此处没有props
console.log(this.props);//这个是undefined。请在super里传递props,试试
}
render(){
return (
<div>{this.props.name}</div>
)
}
}
ReactDOM.render(<Home name="hi"/>,document.getElementById("box"))
所以:
组件的super里如果不传递props
1)、可以在其它函数里使用this.props,因为,组件的构造函数会再次设置props的
2)、在构造函数里,this.props是undefined。即:this.props.属性名会报错。因为,React.Component的构造函数没有增加props属性。
7、为什么建议传递给setState函数的参数是回调函数而不是对象?
因为,this.setState()函数内部是异步执行的。
1)、如果给setState()的参数写成对象的话,你会误以为它是同步的。进而,如果想使用新的值,就会下意识调用setState完毕后,直接使用新的msg的值,
如下代码,你是否会下意识(“直观”)地觉得是异步呢,哈哈
this.setState({
msg:"hello"
});
console.log(this.state.msg);// 亲,这个值不是hello
2)、如果写成回调函数的话,你就不会有以上的误解。
如下代码:
//改变状态前后都想做一些事情:
this.setState((prevState)=>{
// prevState:是旧值
console.log("prevState",prevState)
return {
age:15
}
},()=>{
// this.state:就是新值。
console.log(this.state.age);
});
8、React中的setState是同步执行还是异步执行?如果是异步的?怎么拿到执行后的state?
setState是异步的。
如果要拿到修改后的状态,需要使用回调函数的方式,如下:
//改变状态后想做一些事情:
this.setState({
属性名:属性值
}, () => {
//一般是用于在setState之后做一些操作
//this.state == 修改之后的state
})
9、为什么不能直接用以下办法更新state
this.state.msg = “hello”;
因为,这样不会引起组件的重新渲染,所以,数据修改后没法 呈现在页面上。
而调用setState()函数,会引起组件的重新渲染,这样更新的数据就会呈现在页面上。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/31260.html