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

时间:2019-08-20 00:35:46

标签: javascript reactjs

我使用带有钩子的功能性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次重新渲染

2 个答案:

答案 0 :(得分:2)

调用useState()钩子的setter方法的副作用是,这样做会触发组件重新渲染。

避免冗余重新渲染的一种解决方案是像这样合并组件状态:

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>
}

答案 1 :(得分:0)

  

React将事件处理程序包装在对   unstable_batchedUpdates(),以便您的处理程序在   打回来。该回调内部触发的任何状态更新都将是   分批。在该回调之外触发的任何状态更新都不会   分批。超时,承诺和异步功能将最终执行   在该回调之外,因此无法批量处理。

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