簡體   English   中英

如何避免 getInitialState() function 用於 useReducer( reducer, getInitialState() ) 在每次渲染時運行?

[英]How to avoid getInitialState() function used in useReducer( reducer, getInitialState() ) from running on every render?

請參閱下面的片段。

通過做這個:

React.useState(()=>getInitialState2());

您避免在每次渲染時運行useState中使用的getInitialState2()

但這似乎不適用於useReducer鈎子。

問題

有沒有辦法避免在每次渲染的useReducer掛鈎的initialState參數中使用 function ?

 function App() { const [state,dispatch] = React.useReducer(reducer,getInitialState()); const [state2,setState2] = React.useState(()=>getInitialState2()); return( <React.Fragment> <div> State: {state} </div> <div> State2: {state2} </div> <div> <button onClick={() => dispatch({type: "INCREMENT"})}>+</button> <button onClick={() => dispatch({type: "DECREMENT"})}>-</button> </div> </React.Fragment> ); } function getInitialState() { console.log("From getInitialState..."); return 0; } function getInitialState2() { console.log("From getInitialState2..."); return 0; } function reducer(state,action) { switch(action.type) { case "INCREMENT": { return state + 1; } case "DECREMENT": { return state - 1; } default: { return state; } } } 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。 此外,惰性初始化是useReducer的第三個參數。 無論您作為useReducer的第二個參數提供什么,都將傳遞給惰性初始化 function,但您可以忽略它。

const [state,dispatch] = React.useReducer(reducer, null, getInitialState);

或者用箭頭 function 包裹它,如果你需要用 props 中的值初始化它:

const [state,dispatch] = React.useReducer(reducer, null, () => getInitialState(props.something));

演示:

 function App() { const [state,dispatch] = React.useReducer(reducer,null,getInitialState); const [state2,setState2] = React.useState(()=>getInitialState2()); return( <React.Fragment> <div> State: {state} </div> <div> State2: {state2} </div> <div> <button onClick={() => dispatch({type: "INCREMENT"})}>+</button> <button onClick={() => dispatch({type: "DECREMENT"})}>-</button> </div> </React.Fragment> ); } function getInitialState() { console.log("From getInitialState..."); return 0; } function getInitialState2() { console.log("From getInitialState2..."); return 0; } function reducer(state,action) { switch(action.type) { case "INCREMENT": { return state + 1; } case "DECREMENT": { return state - 1; } default: { return state; } } } 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"/>

由於每次渲染發生時組件都會重新運行,因此一種選擇是僅在組件外部檢索一次初始 state:

 const initialState1 = getInitialState(); function App() { const [state,dispatch] = React.useReducer(reducer, initialState1); const [state2,setState2] = React.useState(()=>getInitialState2()); return( <React.Fragment> <div> State: {state} </div> <div> State2: {state2} </div> <div> <button onClick={() => dispatch({type: "INCREMENT"})}>+</button> <button onClick={() => dispatch({type: "DECREMENT"})}>-</button> </div> </React.Fragment> ); } function getInitialState() { console.log("From getInitialState..."); return 0; } function getInitialState2() { console.log("From getInitialState2..."); return 0; } function reducer(state,action) { switch(action.type) { case "INCREMENT": { return state + 1; } case "DECREMENT": { return state - 1; } default: { return state; } } } 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM