首页 文章

ReactJS - 在调用“setState”的任何时候都会调用render吗?

提问于
浏览
339

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

如果是这样,为什么?我认为这个想法是React只在需要的时候渲染 - 当状态改变时 .

在下面的简单示例中,两个类在单击文本时再次呈现,尽管状态在后续单击时不会更改,因为onClick处理程序始终将 state 设置为相同的值:

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

我希望渲染只会在 state 数据发生变化时才会发生 .

以下是示例代码as a 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>
[1]: http://jsfiddle.net/fp2tncmb/2/

3 回答

  • 402

    是 . 每当我们调用setState时它调用render()方法,而当“shouldComponentUpdate”返回false时 .

  • 75

    不,当状态发生变化时,React不会渲染所有内容 .

    • 每当组件变脏(其状态发生变化)时,该组件及其子组件将被重新呈现 . 这在某种程度上是尽可能少地重新渲染 . 渲染的唯一时间是't called is when some branch is moved to another root, where theoretically we don't需要重新渲染任何东西 . 在您的示例中, TimeInChildMain 的子组件,因此当 Main 的状态发生更改时,它也会重新呈现 .

    • React不比较状态数据 . 调用 setState 时,它会将组件标记为脏(这意味着需要重新渲染) . 需要注意的重要一点是,尽管调用了组件的 render 方法,但只有当输出与当前DOM树不同时才会更新真正的DOM(在虚拟DOM树和文档的DOM树之间进行区分) . 在您的示例中,即使 state 数据没有't changed, the time of last change did, making Virtual DOM different from document'的DOM,因此HTML也会更新 .

  • 1

    每次调用setState时,React都会重新渲染所有组件和子组件吗?

    默认情况下 - 是的 .

    有一个方法 boolean shouldComponentUpdate(object nextProps, object nextState) ,每个组件都有这个方法,它负责确定“应该组件更新(运行渲染功能)?”每次更改状态或从父组件传递新的道具时 .

    您可以为组件编写自己的shouldComponentUpdate方法实现,但默认实现始终返回true - 意味着始终重新运行render函数 .

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

    默认情况下,shouldComponentUpdate始终返回true以防止在状态发生变异时出现细微错误,但是如果您小心将状态始终视为不可变并且只读取render()中的props和state,那么您可以使用实现覆盖shouldComponentUpdate将旧道具和州与其替代品进行比较 .

    问题的下一部分:

    如果是这样,为什么?我认为这个想法是React只在需要的时候渲染 - 当状态改变时 .

    我们称之为“渲染”的步骤分为两步:

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

    • 本机DOM渲染:只有在虚拟DOM中更改它们并且根据需要更改时,React才会更改浏览器中的真实DOM节点 - 这就是React的优秀功能,它可以优化真正的DOM突变并使React快速运行 .

相关问题