簡體   English   中英

更改 state 后立即重新渲染

[英]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.

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