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

2020/09/25 06:41 · javascript ·  · 0评论

每次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>

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

默认情况下-是。

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

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

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

默认情况下,在状态发生适当变化时,shouldComponentUpdate始终返回true以防止细微的错误,但是如果您始终将状态视为不可变并在prop()和prop()中是只读状态,则可以使用比较旧道具和状态及其替换的实现。

问题的下一部分:

如果是这样,为什么?我以为这个想法是当状态改变时,React只渲染所需的内容。

我们可以将“渲染”分为两个步骤:

  1. 虚拟DOM渲染:调用render方法时,它将返回组件的新虚拟dom结构。如前所述,此渲染方法总是在您调用setState()时调用,因为默认情况下shouldComponentUpdate始终返回true。因此,默认情况下,React中没有优化。

  2. 本机DOM渲染:仅当在虚拟DOM中更改了真实DOM节点时,React才更改浏览器中的真实DOM节点,并且需要的次数很少-这是React的一项出色功能,它可以优化真实DOM变异并加快React的速度。

不,状态改变时,React不会呈现所有内容。

  • 每当组件变脏(状态更改)时,都会重新渲染该组件及其子代。在某种程度上,这是要尽可能少地重新渲染。唯一不调用render的时候就是将某个分支移到另一个根,从理论上讲,我们不需要重新渲染任何东西。在您的示例中,TimeInChild是的子组件Main,因此在状态Main更改时也会重新呈现

  • React不比较状态数据。setState被调用时,它标记组件为脏(这意味着它需要重新呈现)。需要注意的重要一点是,尽管render调用了组件的方法,但是仅当输出与当前DOM树不同(也就是在虚拟DOM树和文档的DOM树之间进行区分)时,才更新实际DOM。在您的示例中,即使state数据没有更改,上次更改的时间也发生了更改,从而使Virtual DOM与文档的DOM不同,因此更新了HTML。

即使在这里的许多其他答案中都已说明,该组件也应该:

  • 实现shouldComponentUpdate仅在状态或属性更改时呈现

  • 切换到扩展PureComponent,后者已经在shouldComponentUpdate内部实现了用于浅表比较方法。

这是一个使用的示例,shouldComponentUpdate仅适用于此简单的用例和演示目的。使用此功能时,组件将不再在每次单击时重新呈现其自身,而是在首次显示时以及单击一次后呈现。

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'});
    },

    shouldComponentUpdate: function(nextProps, nextState) {
      if (this.state == null)
        return true;
  
      if (this.state.test == nextState.test)
        return false;
        
      return true;
  },

    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>

是。每当“ shouldComponentUpdate”返回false时,它将每次调用setState时调用render()方法。

“丢失更新”的另一个原因可能是下一个:

如果是问题,则U可以避免在更新过程中设置状态,您应该像这样检查状态参数值

static getDerivedStateFromProps(props: TimeCorrectionProps, state: TimeCorrectionState): TimeCorrectionState {
   return state ? state : {disable: false, timeCorrection: props.timeCorrection};
}

另一种解决方案是向状态添加一个初始化的属性,并在第一次设置它(如果状态被初始化为非null值)。

并非所有组件。

state组分看起来像整个APP的状态的瀑布的来源。

因此更改发生在setState调用的位置。renders然后从那里叫如果您使用的是纯组分,render将被跳过。

似乎在使用React钩子时不再是公认的答案。您可以在此代码沙箱中看到,当状态设置为相同的值时,将重新渲染类组件,而在功能组件中,将状态设置为相同的值不会导致重新渲染。

https://codesandbox.io/s/still-wave-wouk2?file=/src/App.js

本文地址:http://javascript.askforanswer.com/reactjs-meicidiaoyong-setstateshidouhuidiaoyongxuanranma.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!