React是否在每次调用setState()时重新渲染所有组件和子组件?
如果有,为什么?我认为React的想法是只渲染需要的部分-当状态改变时。
在下面这个简单的例子中,当文本被点击时,这两个类都会再次呈现,尽管在随后的点击中状态不会改变,因为onClick处理程序总是将状态设置为相同的值:
this.setState({'test':'me'});
我本以为只有在状态数据发生变化时才会发生渲染。
下面是这个例子的代码,作为JS的Fiddle,并嵌入代码片段:
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="https://cdnjs.cloudflare.com/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>
不,React不会在状态改变时渲染所有内容。
Whenever a component is dirty (its state changed), that component and its children are re-rendered. This, to some extent, is to re-render as little as possible. The only time when render isn't called is when some branch is moved to another root, where theoretically we don't need to re-render anything. In your example, TimeInChild is a child component of Main, so it also gets re-rendered when the state of Main changes.
React doesn't compare state data. When setState is called, it marks the component as dirty (which means it needs to be re-rendered). The important thing to note is that although render method of the component is called, the real DOM is only updated if the output is different from the current DOM tree (a.k.a diffing between the Virtual DOM tree and document's DOM tree). In your example, even though the state data hasn't changed, the time of last change did, making Virtual DOM different from the document's DOM, hence why the HTML is updated.
React是否在每次调用setState时重新渲染所有组件和子组件?
默认情况下是。
有一个方法布尔shouldComponentUpdate(对象nextProps,对象nextState),每个组件都有这个方法,它负责确定每次你改变状态或从父组件传递新道具时“组件是否应该更新(运行渲染函数)?”
你可以为你的组件编写自己的shouldComponentUpdate方法实现,但是默认实现总是返回true——这意味着总是重新运行渲染函数。
引用自官方文档http://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
默认情况下,shouldComponentUpdate总是返回true来防止
细微的bug发生时状态是突变的,但如果小心的话
始终将状态视为不可变的,并且从props和state到只读
在render()中,您可以使用
实现,将旧的道具和状态与其进行比较
更换。
你问题的下一部分:
如果有,为什么?我认为React只在需要的时候渲染一点点——当状态改变的时候。
我们称之为“渲染”的有两个步骤:
Virtual DOM renders: when render method is called it returns a new virtual dom structure of the component. As I mentioned before, this render method is called always when you call setState(), because shouldComponentUpdate always returns true by default. So, by default, there is no optimization here in React.
Native DOM renders: React changes real DOM nodes in your browser only if they were changed in the Virtual DOM and as little as needed - this is that great React's feature which optimizes real DOM mutation and makes React fast.
不,React不会在状态改变时渲染所有内容。
Whenever a component is dirty (its state changed), that component and its children are re-rendered. This, to some extent, is to re-render as little as possible. The only time when render isn't called is when some branch is moved to another root, where theoretically we don't need to re-render anything. In your example, TimeInChild is a child component of Main, so it also gets re-rendered when the state of Main changes.
React doesn't compare state data. When setState is called, it marks the component as dirty (which means it needs to be re-rendered). The important thing to note is that although render method of the component is called, the real DOM is only updated if the output is different from the current DOM tree (a.k.a diffing between the Virtual DOM tree and document's DOM tree). In your example, even though the state data hasn't changed, the time of last change did, making Virtual DOM different from the document's DOM, hence why the HTML is updated.