尽管状态修改,React 不会重新渲染组件

时间:2021-05-17 08:12:12

标签: reactjs react-hooks

我有一个要过滤/排序的卡片列表,使用 4 个不同的选择/输入字段。

对于 4 个过滤器中的 3 个,效果很好。卡片过滤排序成功,过滤器可以合并没有问题。

不过,在第一个上,我必须单击它两次,或者单击一次然后激活另一个过滤器,才能查看卡片中的变化。

我不明白为什么这个特定的过滤器不会触发卡片的重新渲染,因为像所有其他过滤器一样,它的值在状态中更新,如下所示:

 const [filters, setFilters] = useState({
    orderByFilter: null, // doesn't work the first time
    titleFilter: null,
    dateFilter: '',
    searchFilter: '',
  });

我为解决异步状态更新所做的是观察 useEffect 钩子中过滤器的变化,以更新过滤后的数据。同样,适用于其他 3 个过滤器。

useEffect(() => {
    setFilteredData(filterCards(dataCards, filters));
    // forceUpdate();
  }, [filters]);

当我在 setFilteredData 之后触发强制更新时,我能够使其适用于 4 个过滤器:

const forceUpdate = React.useReducer(() => ({}), {})[1] as () => void;

但这对我来说就像一个黑客,表明我不明白真正的问题是什么。

有没有办法在没有这个强制更新的情况下完成这项工作?

PS:编辑代码以避免被搜索引擎索引,因为这是半敏感数据。

1 个答案:

答案 0 :(得分:1)

我认为这里的问题是,对于您使用的订单过滤器,sort 对数组 in place 进行排序,因此最终您会得到相同的数组,但具有已排序的值,即React 不会将其作为更改接收,即不会触发渲染。为了解决这个问题,在初始化过滤器数组时,尝试使用它的副本:

 let filteredArray = [...valueListCards];

此外,将过滤后的数据保存到状态的方法也不是最优的,因为它会导致这些类型的错误,而且您需要使状态与实际数据保持同步。一个更好的主意是 derive the state,它基本上是在渲染时应用过滤器。