ReactJS学习笔记 (三)React Element

Sat 05 January 2019 / In categories Web

ReactJS

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中(这步操作是 get­Derived­State­From­Props()完成的);如果内部状态和之前的发生变化(should­Component­Update),那么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()这个操作是异步的。*

(本篇完)

Load Disqus Comments