繁体   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