[英]useState and useRef initial values getting computed every re-render
[英]How to avoid the useState function parameter (to get initial values) from being executed on every render?
請參閱下面的代碼片段, 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'));
<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"/>
不要直接在 useState 內部調用useState
,通過匿名 function 來觸發 function。 參考官方文檔。
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'));
<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"/>
嘗試使用React.useMemo
進行記憶
function getInitialState() { console.log('Executing getInitialState...'); return { foo: 'bar' }; } function App() { const getInitial = React.useMemo(() => getInitialState(), []); const [myState, setMyState] = React.useState(getInitial); 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'));
<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" />
您需要根據文檔在 function 中計算您的 state :
const [myState,setMyState] = useState(() => {
const initialState = getInitialState();
return initialState;
});
或更短:
const [myState, setMyState] = useState(getInitialState);
又一個鈎子陷阱!
所有好的解決方案,我的兩分錢=上面多米尼克的較短解決方案。 :)
You're passing a computed function (the result of the function is passed to useState) If you pass your function, React knows that it needs to call that function only the first time:
function App() { function getInitialState() { console.log('Executing getInitialState...'); return({ foo: 'bar' }); } const [myState,setMyState] = React.useState(getInitialState); // <-- pass the function, not the call to the function (result) 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'));
<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"/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.