在函数体中调用状态设置器时,效果不会运行(甚至不会运行一次)

时间:2019-11-08 10:09:08

标签: reactjs react-hooks

请帮助我了解在函数体内调用状态设置器的方式

const MyComponent = () => {
  const [state, setState] = useState(0);
  const flagRef = useRef(true);

  if (flagRef.current) setState(1);

  useEffect(() => {
    flagRef.current = false;
  });

  return 'MyComponent';
}

运行此代码将导致无限重新渲染。根据React文档,它说setState函数用于更新状态。它接受一个新的状态值,并使该组件重新渲染入队。我解释为,下一个渲染将被排队并在当前渲染完成后运行,包括运行效果。但是,这种效果根本不会运行,甚至不会运行一次,并且即使代码再次更新相同的状态(即1

),重新渲染的链也将永远发生而没有任何救助。

请帮助我理解这段代码的内部工作。

1 个答案:

答案 0 :(得分:0)

您的代码的有效版本(以下代码段):

注意::您还可以将依赖项数组添加到useEffect中,以确定何时应运行该效果。

https://reactjs.org/docs/hooks-effect.html

const MyComponent = () => {
  
  console.log('MyComponent is rendering...');
  
  const [state, setState] = React.useState(0);
  const flagRef = React.useRef(true);

  React.useEffect(() => {
    console.log('useEffect is running...');
    if (flagRef.current) {
      console.log('flagRef is true... will call setState(1) and turn flag to false...');
      setState(1);
      flagRef.current = false;
    }
    else {
      console.log('flagRef is false... I will not do anything');    
    }
  });

  return (
    <div>My state: {state}</div>
  );
}

ReactDOM.render(<MyComponent/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>