ReactJS - 每次调用“setState”时都会调用渲染吗?

新手上路,请多包涵

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

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

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

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

我原以为只有在 state 数据发生变化时才会进行渲染。

这是示例的代码, 作为 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>

原文由 Brad Parks 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.8k
2 个回答

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

默认情况下 - 是的。

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

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

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

默认情况下, shouldComponentUpdate 总是返回 true 以防止

当状态发生变化时出现细微的错误,但如果你小心

始终将 state 视为不可变的,并且从 props 和 state 中只读

在 render() 然后你可以用一个覆盖 shouldComponentUpdate

将旧的道具和状态与其进行比较的实现

替代品。

你问题的下一部分:

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

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

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

  2. 原生 DOM 渲染:React 仅在虚拟 DOM 中更改真实 DOM 节点时才会更改浏览器中的真实 DOM 节点,并且只需少量更改 - 这是 React 的伟大功能,可优化真实 DOM 突变并使 React 快速运行。

原文由 Petr 发布,翻译遵循 CC BY-SA 4.0 许可协议

不,React 不会在状态改变时渲染所有内容。

  • 每当一个组件脏了(它的状态改变了),那个组件和它的子组件就会被重新渲染。这在某种程度上是尽可能少地重新渲染。唯一不调用 render 的情况是当某个分支移动到另一个根时,理论上我们不需要重新渲染任何东西。在您的示例中, TimeInChildMain 的子组件,因此当 Main -be-336 的状态更改时,它也会重新呈现。

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

原文由 tungd 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题