ReactJS学习笔记系列。
React Element的挂载
虽然React Element模仿HTML Element,但是React Element毕竟是JavaScript代码,需要动态挂载到HTML的DOM里面去。
我们需要先在HTML里面设置一个挂载点,通常是一个空的div元素: <div id="root"></div>
。
然后我们使用ReactDOM提供的API来把React挂载到目标之上:
const mountNode = document.getElementById("root")
class HelloMessage extends React.Component {
render() {
return (<div> Hello {this.props.name} </div>);
}
}
ReactDOM.render(
<HelloMessage name="Bincy" />,
mountNode
);
这样导致了一个结果,React Element的生命周期依赖于它挂载的HTML Element的生命周期。
有一个图解释了React Element的生命周期:react-lifecycle-methods-diagram
从图上可以看到React Element的生命周期包括三个阶段,分别是:Mounting,Updating和Unmounting。每个阶段结束前后都有回调函数可以用来通知用户,这些回调函数分别是:componentDidMount, componentDidUpdate, componentWillUnmount。
在componentDidMount, componentDidUpdate, componentWillUnmount这些回调函数里面尽量避免修改React Element的状态
另外在Updating阶段React Element进入一个更新循环,在这个循环中响应外部输入,然后更新DOM。
对DOM的更新可以看作是事件响应的副作用。
在这个响应循环里,有三种输入,分别是:New props, setState()和forceUpdate()。第一种输入New props是在React Element创建的时候的输入参数,后面两种是React在处理外部事件时,根据需要而进行的函数调用。React会把这三种输入转化为内部的状态,保存在属性state
中(这步操作是 getDerivedStateFromProps()完成的);如果内部状态和之前的发生变化(shouldComponentUpdate),那么React就需要重新执行render操作,否则什么都不做。
render操作必须是pure的操作,也就是说对于相同的输入必须产生相同的结果,另外render操作不能对DOM进行操作
在执行render操作之后,会生成一个新的VirtualDOM(getSnaphotBeforeUpdate),如果这个VirtualDOM和之前的相比没有变化,则React不需要去更新真实的HTML DOM;如果变化存在,那么React会只去更新那些有必要修改的部分。
为了进行前后对比,React要求state和VirtualDOM都是Immutable的,也就是只能生成新的state和新的VirtualDOM,保证原有的state和VirtualDOM还可继续访问。
setState
前面提到,React的state是内部的、私有的,并且必须被当作Immutable对待,否则就会出问题。所以你不能直接去修改state的属性(就算是子Component也不能访问父Component的内部状态),而是要通过setState()
来修改。
setState()
接受两种形式的参数,一种是一个对象,setState()
会把这个对象的属性合并到既有state中;另一种参数形式是一个函数,用来更新既有state。
使用setState()
有很多注意点:
- 由于state必须保持immutable,所以一个常见的错误是代码直接修改了state的属性。
- 另一个常见的错误是在React Element的constructor里面使用了
setState()
。这时候React Element还没有进入更新周期,所以使用setState()
会导致意想不到的结果。 - 最早可以在componentDidMount()的时候调用
setState()
,虽然这会导致二次render操作,但此时DOM还没有更新,所以代价不高。 - 在componentWillUnmount()时候不需要调用
setState()
,因为React Element即将从DOM中卸载。 setState()
只是告诉React要更新状态,具体什么时候更新确是由React自己决定的。所以setState()
这个操作是异步的。*
(本篇完)
2022-10-10更新
react自身不管理外部的、全局的状态,所以就有一众状态管理器们帮react做这些事:
-
函数式
- redux,单store
- zustand,可以支持多store
-
对象式
- mobx,MVVM式
-
寄居式(依赖于react自身)
- recoil
- jotai
(更新完)