繁体   English   中英

使用useEffect时,react组件会渲染几次

[英]The react component renders several times when using useEffect

我使用带有钩子的功能性React组件。

const [loaded, setLoaded] = React.useState(null);
const [title, setTitle] = React.useState(title);

React.useEffect(() => {
    //...
    fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then(response => response.json())
      .then(json => {
          setLoaded(true);
          setTitle(title);
      });
}, []);

在这种情况下,组件将渲染两次。 一方面,这似乎是合乎逻辑的。

但是我在这个组件中也有一个复选框处理程序

const changeHandler = event => {
    //...
    setTotal(new_total);
    setError(false);
};

在这种情况下,尽管状态也会更改2次,但不会进行两次渲染。 我不明白为什么会这样。

PS

解决这个问题没有问题,我想知道为什么这就是事实

UPD

如果我设置为useEffect

setLoaded(true);
setTitle(title);
setTitle2(title);
setTitle3(title);

将重新渲染4次,如果我在changeHandler设置

setTotal(new_total);
setError(false);
setError2(false);
setError3(false);

将重新渲染1次

调用useState()挂钩的setter方法的useState()是,这样做会触发组件重新呈现。

一种避免冗余重新渲染的解决方案是合并组件状态,如下所示:

function functionalComponent() {

    /* Merge both values into common "state object */
    const [{ loaded, title }, setState] = React.useState({ 
        loaded : null, 
        title : "inital title" 
    });

    React.useEffect(() => {

        /* 
        Single call to setState triggers on re-render only. The
        value of "new title" for title could have been set in the
        inital state, however I set it here to show how combined
        state can be updated with a single call to setState()  
        */
        setState({ loaded : true, title : "new title" })

        /*
        setLoaded(true);
        setTitle(title);
        */
    }, []);

    /* Use loaded and title variables as needed during render */
    return <div>{ loaded } - { title }</div>
}

React将事件处理程序包装在对unstable_batchedUpdates()的调用中,以便您的处理程序在回调中运行。 该回调内部触发的任何状态更新将被分批处理。 在该回调之外触发的任何状态更新都不会被批处理。 超时,承诺和异步函数最终将在该回调之外执行,因此将不进行批处理。

https://github.com/facebook/react/issues/14259

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM