如何避免在每次渲染时执行 useState 函数参数(以获取初始值)?

cbd*_*per 6 javascript reactjs react-hooks

请参阅下面的代码片段,该代码段getInitialState在每次渲染时执行。即使从它返回的值仅在第一次渲染期间使用。

我知道这是正常的 Javascript 行为。但是有没有办法使用 React 来避免它?

function App() {

  function getInitialState() {
    console.log('Executing getInitialState...');
    return({
      foo: 'bar'
    });
  }

  const [myState,setMyState] = React.useState(getInitialState());
  const [myBoolean,setMyBoolean] = React.useState(false);
  
  return(
    <React.Fragment>
      <div>I am App</div>
      <div>My state: {JSON.stringify(myState)}</div>
      <div>My boolean: {JSON.stringify(myBoolean)}</div>
      <button onClick={()=>setMyBoolean((prevState) => !prevState)}>Force Update</button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<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"/>
Run Code Online (Sandbox Code Playgroud)

小智 8

内部不要直接调用函数useState,传递一个匿名函数来触发函数。参考官方文档

  function getInitialState() {
    console.log('Executing getInitialState...');
    return({
      foo: 'bar'
    });
  }
  
function App() {

  const [myState,setMyState] = React.useState(()=>getInitialState());
  const [myBoolean,setMyBoolean] = React.useState(false);
  
  return(
    <React.Fragment>
      <div>I am App</div>
      <div>My state: {JSON.stringify(myState)}</div>
      <div>My boolean: {JSON.stringify(myBoolean)}</div>
      <button onClick={()=>setMyBoolean((prevState) => !prevState)}>Force Update</button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<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"/>
Run Code Online (Sandbox Code Playgroud)


Dom*_*nic 6

您需要根据文档计算函数内的状态:

const [myState,setMyState] = useState(() => {
  const initialState = getInitialState();
  return initialState;
});
Run Code Online (Sandbox Code Playgroud)

或者更短:

const [myState, setMyState] = useState(getInitialState);
Run Code Online (Sandbox Code Playgroud)

又一个钩子陷阱!