简体   繁体   English

React.js 状态仅正确更新一次,然后失败

[英]React.js State updating correctly only once, then failing

I have a parent and a child component.我有一个父组件和一个子组件。 There are 3 props the parent provides out of which 1 is not updating correctly.父级提供了 3 个道具,其中 1 个没有正确更新。

Following is the parent component.以下是父组件。 The prop in question is selectedFilters (which is an object where keys are mapped to sets ) and the relevant update function is filterChanged (this is passed to the child)有问题的道具是selectedFilters (这是一个将键映射到set的对象),相关的更新函数是filterChanged (这是传递给孩子的)

import filters from "../../data/filters";    //JSON data

const Block = (props) => {
  const [selectedFilters, setSelectedFilters] = useState({versions: new Set(), languages: new Set()});
  console.log(selectedFilters);

  const filterChanged = useCallback((filter_key, filter_id) => {
    setSelectedFilters((sf) => {
      const newSFSet = sf[filter_key]; //new Set(sf[filter_key]);
      if (newSFSet.has(filter_id)) {
        newSFSet.delete(filter_id);
      } else {
        newSFSet.add(filter_id);
      }
      const newSF = { ...sf, [filter_key]: new Set(newSFSet) };
      return newSF;
    });
  }, []);

  return (
    <FilterGroup
      filters={filters}
      selectedFilters={selectedFilters}
      onFilterClick={filterChanged}
    ></FilterGroup>
  );
};

export default Block;

The following is the child component: (Please note that while the Filter component runs the filterChanged function, I think it is irrelevant to the error)以下是子组件:(请注意,虽然Filter组件运行filterChanged函数,但我认为它错误无关

import Filter from "./Filter/Filter";

const FilterGroup = (props) => {
  const { filters, selectedFilters, onFilterClick } = props;
  console.log(selectedFilters);

  const filter_view = (
    <Container className={styles.container}>
      {Object.keys(filters).map((filter_key) => {
        const filter_obj = filters[filter_key];
        return (
          <Filter
            key={filter_obj.id}
            filter_key={filter_key}
            filter_obj={filter_obj}
            selectedFilterSet={selectedFilters[filter_key]}
            onFilterClick={onFilterClick}
          />
        );
      })}
    </Container>
  );

  return filter_view;
};

export default FilterGroup;

When running the application, I find that the selectedFilters updates correctly only once.运行应用程序时,我发现 selectedFilters 仅正确更新一次。 After that, it only changes temporarily in the main Block.tsx , but eventually goes back to the first updated value.之后,它只会在主Block.tsx 中临时更改,但最终会返回到第一个更新的值。 Also, FilterGroup.tsx only receives the first update.此外, FilterGroup.tsx仅接收第一次更新。 After that, it never receives any further updated values.之后,它再也不会收到任何进一步更新的值。

Here are the logs:以下是日志: 在此处输入图片说明

After some experimentation, it is clear that the problem originates from the filterChanged function.经过一些实验,很明显问题源于filterChanged函数。 But I cannot seem to figure out why the second update is temporary AND does not get passed on to the child.但是我似乎无法弄清楚为什么第二次更新是暂时的并且不会传递给孩子。

Any ideas?有任何想法吗? Thanks in advance.提前致谢。 (If any other info is required, pls do mention it) (如果需要任何其他信息,请务必提及)

I don't think you actually want your filterChanged function to be wrapped with useCallback , especially with an empty deps array.我不认为你真的希望你的filterChanged函数被useCallback包裹,尤其是一个空的 deps 数组。 with the empty deps array, I believe useCallback will fire once on initial render, and memoize the result.使用空的 deps 数组,我相信useCallback会在初始渲染时触发一次,并记住结果。 You may be able to add filter_key and filter_id to the dependency array, but useCallback tends to actually slow simple functions down, instead of adding any real performance benefit, so you may just want to get rid of the useCallback completely and switch filterChanged to a regular arrow function.您也许可以将filter_keyfilter_id添加到依赖项数组中,但 useCallback 实际上往往会减慢简单函数的速度,而不是增加任何真正的性能优势,因此您可能只想完全摆脱useCallback并将filterChanged切换为常规箭头函数。

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

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