[英]re-render as soon as the state is changed
我有這樣的 app.js 文件
export const App = () => {
const [selectedMeals, setSelectedMeals] = useState<string[]>(["allItems"]);
const onCheckHandler = (e: any) => {
const checkedValue = e.target.value;
if (e.target.checked && checkedValue !== "allItems") {
setSelectedMeals(
[...new Set([...selectedMeals, checkedValue])].filter(
(item) => item !== "allItems"
)
);
} else if (e.target.checked && checkedValue === "allItems") {
setSelectedMeals(["allItems"]);
} else {
setSelectedMeals(selectedMeals.filter((item) => item !== checkedValue));
}
};
return (
<MenuFilter
onClick={hideMenuModalHandler}
onCheck={onCheckHandler}
checkedItems={selectedMeals}
/>
);
}
菜單過濾器又使用一個checkbox
組件來呈現幾個復選框,這些復選框的選中狀態取決於我傳遞給菜單過濾器組件的selectedMeals
道具
export const MenuFilter = ({
onClick,
onCheck,
checkedItems,
}: MenuFilterProps) => {
const excelDataContextObject = useContext(excelDataContext);
const excelData = excelDataContextObject.excelData;
const colorModeState = useContext(colorModeContext);
const toggled = colorModeState.toggled;
let meals = [...new Set(excelData.map((item: menuItem) => item.Meal))];
return (
<Modal filterItems={meals} toggled={toggled} onClick={onClick}>
<div
className={`${styles["modal-header"]} grid ${
toggled ? "theme-dark" : "theme-light"
}`}
>
Filter Menu
</div>
<div
className={`${styles["menu-filter"]} grid ${
toggled ? "theme-dark" : "theme-light"
}`}
>
<CheckBox
key={"allItems"}
standAlone={false}
text={"All Items"}
onCheck={onCheck}
isChecked={checkedItems.includes("allItems")}
value={"allItems"}
/>
{meals.map((meal: string) => (
<CheckBox
key={meal}
standAlone={false}
text={meal}
onCheck={onCheck}
isChecked={checkedItems.includes(meal)}
value={meal}
/>
))}
</div>
<div className={`${styles["modal-footer"]}`}>
<button
className={`${styles.ok} ${toggled ? "theme-dark" : "theme-light"}`}
>
OK
</button>
<button
className={`${styles.cancel} ${
toggled ? "theme-dark" : "theme-light"
}`}
onClick={onClick}
>
Cancel
</button>
</div>
</Modal>
);
};
我讀到,當 state 作為道具傳遞時,一旦 state 發生變化,就會重新渲染,但這並沒有發生。
selectedMeals
state 使用allItems
初始化,然后進行管理,以便在單擊任何其他項目時,設置該項目和allItems
,並且這些individual
的項目可以同時有多個。 state 管理工作正常,但復選框未根據狀態更新!
請參閱此處的視頻( https://youtu.be/Zmfc0MQGaIU ),其中 state 更改(刪除了allItems
並且檢查了allItems
時刪除了其他項目)工作正常,但復選框未正確重新渲染
我做錯了什么,更重要的是如何獲得我想要的結果?
這是因為 setSomething() 僅當且僅當先前和當前 state 不同時才重新渲染組件。 由於 javascript 中的 arrays 是引用類型,所以如果在 js 中編輯一個數組的一項,它仍然不會改變對原始數組的引用。 在js看來,這兩個arrays是一樣的,雖然這兩個arrays里面原來的內容是不一樣的。 這就是為什么 setSomething() 失敗確實檢測到對舊數組所做的更改。 要糾正這個問題,您需要使用擴展運算符,即。 傳播舊價值觀並增加新價值觀。
在您的情況下,您可以嘗試
setSelectedMeals([...selectedMeals, "allItems"]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.