ReactJS – 随时渲染得到调用“setState”被调用?

每次调用setState React是否重新呈现所有组件和子组件?

如果是这样,为什么? 我认为这个想法是React只在需要的时候呈现 – 当状态改变时。

在下面的简单示例中,尽pipe事件状态在随后的点击中没有改变,但是两个类都会在单击文本时再次呈现,因为onClick处理程序始终将state设置为相同的值:

 this.setState({'test':'me'}); 

我会期望渲染只会发生在state数据已经改变的情况下。

下面是该示例的代码, 作为JS小提琴和embedded式代码片段:

 var TimeInChild = React.createClass({ render: function() { var t = new Date().getTime(); return ( <p>Time in child:{t}</p> ); } }); var Main = React.createClass({ onTest: function() { this.setState({'test':'me'}); }, render: function() { var currentTime = new Date().getTime(); return ( <div onClick={this.onTest}> <p>Time in main:{currentTime}</p> <p>Click me to update time</p> <TimeInChild/> </div> ); } }); ReactDOM.render(<Main/>, document.body); 
 <script src="ajax/libs/react/15.0.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script> 
 [1]: http://jsfiddle.net/fp2tncmb/2/ 

每次调用setState时,React是否重新呈现所有组件和子组件?

默认 – 是的。

有一个方法boolean shouldComponentUpdate(object nextProps,object nextState) ,每个组件都有这个方法,它负责确定“应该组件更新(运行render函数)吗? 每次你改变状态或从父母组件传递新的道具

你可以为你的组件编写自己的shouldComponentUpdate方法的实现,但是默认的实现总是返回true,意思是总是重新运行render函数。

从官方文档引用http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate

默认情况下,shouldComponentUpdate总是返回true,以防止状态发生变化时产生微妙的错误,但是如果你小心总是将状态视为不可变,并且只能从render()中的props和state中读取,那么可以用一个实现来覆盖shouldComponentUpdate比较旧的道具和国家与他们的替代品。

你的问题的下一部分:

如果是这样,为什么? 我认为这个想法是React只在需要的时候呈现 – 当状态改变时。

我们可以称之为“渲染”有两个步骤:

  1. 虚拟DOM渲染:当渲染方法调用时,它返回组件的一个新的虚拟DOM结构。 正如我之前提到的,这个render方法在你调用setState()时总是被调用,因为shouldComponentUpdate总是返回true。 因此,默认情况下,React中没有优化。

  2. 原生DOM渲染:只有在虚拟DOM中更改了真正的DOM节点时,React才会更改浏览器中的真实DOM节点 – 这是React的优化真正DOM突变并使React快速完成的function。

不,React在状态改变时不会渲染所有东西。

  • 每当一个组件变脏(其状态改变)时,该组件及其子组件将被重新渲染。 这在一定程度上是要尽可能less地重新渲染。 渲染不被调用的唯一时间是当某个分支被移动到另一个根时,理论上我们不需要重新渲染任何东西。 在你的例子中, TimeInChildMain一个子组件,所以当Main的状态改变时它也被重新渲染。

  • React不会比较状态数据。 当调用setState ,它将该组件标记为脏(意味着它需要重新渲染)。 需要注意的是,尽pipe调用组件的render方法,但是只有当输出与当前DOM树(也就是虚拟DOM树和文档的DOM树之间的差异)不同时才更新真实DOM。 在你的例子中,即使state数据没有改变,最后一次更改的时间也是这样,使虚拟DOM不同于文档的DOM,因此HTML被更新了。