简体   繁体   English

更改 state 后立即重新渲染

[英]re-render as soon as the state is changed

I have app.js file like so我有这样的 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}
                  />
     
  );


}

The menu filter in turn uses a checkbox component to render several check boxes & the checked status of these checkboxes depends on the selectedMeals prop that i pass to the menufilter component菜单过滤器又使用一个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>
  );
};

I read that when the state is passed as a prop, the re-rendering happens as soon as the state changes but this is not happening.我读到,当 state 作为道具传递时,一旦 state 发生变化,就会重新渲染,但这并没有发生。

The selectedMeals state is initialized with allItems and then managed such that when any other items is click, that items is set & allItems and these individual items can be several at once. selectedMeals state 使用allItems初始化,然后进行管理,以便在单击任何其他项目时,设置该项目和allItems ,并且这些individual的项目可以同时有多个。 The state management works fine but the checkbox is not getting updated based on the state! state 管理工作正常,但复选框未根据状态更新!

See the video here ( https://youtu.be/Zmfc0MQGaIU ) where the state change ( allItems gets removed & when allItems is checked other items get removed) works perfectly but the check boxes are not re-rendering appropriately请参阅此处的视频( https://youtu.be/Zmfc0MQGaIU ),其中 state 更改(删除了allItems并且检查了allItems时删除了其他项目)工作正常,但复选框未正确重新渲染

What am I doing wrong & more importantly how do I get the result I want?我做错了什么,更重要的是如何获得我想要的结果?

It's because setSomething() only re renders the component if and only if the previous and current state is different.这是因为 setSomething() 仅当且仅当先前和当前 state 不同时才重新渲染组件。 Since arrays in javascript are reference types, if you edit an item of an array in js, it still doesn't change the reference to the original array.由于 javascript 中的 arrays 是引用类型,所以如果在 js 中编辑一个数组的一项,它仍然不会改变对原始数组的引用。 In js's eyes, these two arrays are the same, even though the original content inside those arrays are different.在js看来,这两个arrays是一样的,虽然这两个arrays里面原来的内容是不一样的。 That's why setSomething() fails do detect the changes made to the old array.这就是为什么 setSomething() 失败确实检测到对旧数组所做的更改。 to correct this you need to use spread operator ie.要纠正这个问题,您需要使用扩展运算符,即。 spreading the old values and adding new values.传播旧价值观并增加新价值观。

In your case you can try在您的情况下,您可以尝试

 setSelectedMeals([...selectedMeals, "allItems"]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM