简体   繁体   English

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

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

I use functional react component with hooks. 我使用带有钩子的功能性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);
      });
}, []);

In this case, the component is rendered twice. 在这种情况下,组件将渲染两次。 On the one hand, it seems to be logical. 一方面,这似乎是合乎逻辑的。

But I also have a checkbox handler in this component 但是我在这个组件中也有一个复选框处理程序

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

In this case, two rendering does not occur, although state also changes 2 times. 在这种情况下,尽管状态也会更改2次,但不会进行两次渲染。 I can't understand why this is happening. 我不明白为什么会这样。

PS PS

There is no problem to solve this problem, I wonder why this is exactly what happens 解决这个问题没有问题,我想知道为什么这就是事实

UPD : UPD

If I set in useEffect 如果我设置为useEffect

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

will be 4 re-renders, and if I set in changeHandler 将重新渲染4次,如果我在changeHandler设置

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

will be 1 re-render 将重新渲染1次

A side effect of calling setter method of the useState() hook, is that doing so triggers the component to re-render. 调用useState()挂钩的setter方法的useState()是,这样做会触发组件重新呈现。

One solution to avoid the redundant re-render would be to merge your component state like this: 一种避免冗余重新渲染的解决方案是合并组件状态,如下所示:

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 wraps your event handlers in a call to unstable_batchedUpdates() , so that your handler runs inside a callback. React将事件处理程序包装在对unstable_batchedUpdates()的调用中,以便您的处理程序在回调中运行。 Any state updates triggered inside that callback will be batched. 该回调内部触发的任何状态更新将被分批处理。 Any state updates triggered outside that callback will not be batched. 在该回调之外触发的任何状态更新都不会被批处理。 Timeouts, promises, and async functions will end up executing outside that callback, and therefore not be batched. 超时,承诺和异步函数最终将在该回调之外执行,因此将不进行批处理。

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

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

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