我發現 state.elements 在控制臺中發生了變化,即使我還沒有調度。是什么原因?
const initialState = { elements: [['apple','banana'],['rabbit','cat']] };
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count 1 };
case "decrement":
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = React.useReducer(reducer, initialState);
const changeList=()=>{
const elementsArray = Array.from(state.elements);
elementsArray[0][0]='Tiger'
}
return (
<>
Count: {state.elements}
<button onClick={changeList}>Change List without dispatch</button>
</>
);
}
uj5u.com熱心網友回復:
是的,可以在 useReducer 中無需調度即可更改狀態。
就像 React 中的任何狀態一樣,它可以被改變。的useReducer狀態也不例外。
const changeList=()=>{
const elementsArray = Array.from(state.elements);
elementsArray[0][0] = 'Tiger'; // <-- state mutation
}
陣列按參考復制,因此即使 elementsArray是state.elements陣列的副本,陣列元素仍然是對仍在state.elements. 設定elementsArray[0][0]的值"Tiger"具有相同的效果state.elements[0][0]被設定為"Tiger"。
React 中的突變是一個巨大的禁忌,一種反模式。你尤其不要改變 state 或 props。狀態和道具將被視為不可變物件。這就是狀態更新總是需要創建新物件參考的原因。
一個不可變的更新示例:
在這里,您可以淺復制正在更新的每個狀態深度級別。Spread 語法用于淺復制物件屬性,Array.prototype.map并將陣列元素淺復制到新陣列中。
function reducer(state, action) {
switch (action.type) {
case "update_animal":
const { index1, index2, value } = action.payload;
return {
...state,
elements: state.elements.map((outerEl, indexOuter) =>
indexOuter === index1
? outerEl.map((innerEl, indexInner) =>
indexInner === index2 ? value : innerEl
)
: outerEl
)
};
... other cases ...
default:
return state;
}
}
...
dispatch({
type: "update_animal",
payload: {
index1: 0,
index2: 0,
value: "Tiger",
}
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/397846.html
標籤:javascript 反应钩子 使用减速器
上一篇:如何使用react和javascript根據可重用組件中的條件顯示特定文本?
下一篇:無法獲取graphql服務器
