javascript - 传递由 array.filter 计算的值总是会导致 React 中的渲染

标签 javascript reactjs

我有一个组件,可以根据 array.filter 计算要传递的值。不好的是,即使数组的元素完全相同,也会因为每次 props 改变而导致新的渲染。

该组件依赖于从状态计算的值:

        const [targets, setTargets] = useState<Target[]>([]);

这是当我不希望它重新渲染时重新渲染的元素。

        <Map
          settings={mediumKneeboardMapSettings}
          targets={getTargets(kneeboardGroupSelected?.id)}
        />

这里是根据 groupId(如果传递)进行过滤的回调。

  const getTargets = useCallback(
    (groupId?: string) => {
      if (!groupId) {
        return targets;
      }
      const groupTargets = targets.filter(target => target.group === groupId);
      return groupTargets;
    },
    [targets]
  );

每次父渲染时,如果将 id 传递给 getTargetsMap 组件就会重新渲染。如果传递了 undefined,它不会重新渲染。这对我来说很有意义,因为如果传入一个 undefined ,它每次都会返回相同的数组的状态。

但是,如果我传递 id 映射会重新渲染,因为从 filter 方法创建了一个新数组,即使该元素的成员未更改(每个例如,传递相同的 2 个元素时)。该数组包含来自 targets 的原始元素。不好的事情是在每次渲染时,Map 组件都会将其视为传入新目标,即使参数没有更改。这很糟糕,因为 Map 中的效果会在目标更改时执行额外的工作。

如何计算数组的子集作为 props 传递,但如果元素相同,则不会触发对子项的更改?

我正在考虑 useMemo 之类的东西,我需要它来记住输入并保存输出,只要目标不改变(这会导致创建一个新函数),该函数就是纯函数由于回调)。

最佳答案

您可以使用useMemo()来实现此目的

const groupTargets = useMemo(()=>targets.filter(target => target.group === groupId),[targets]);

它仅在目标发生变化时运行 或者在 Map.js 中你可以这样做

导出默认的 React.memo(Map) 这将浅比较 props 并在 props 改变时重新渲染

但是 Kent C Dodds 不鼓励使用 useCallback() useMemo()React.memo() 始终,因为执行这些操作的成本高于重新渲染的成本。引用https://kentcdodds.com/blog/usememo-and-usecallback

关于javascript - 传递由 array.filter 计算的值总是会导致 React 中的渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60707624/

相关文章:

javascript - 用于突出显示文本和从文件中重新加载突出显示的 React 组件

javascript - 以 31 为日期创建日期在输出中给出 30

javascript - 没有选中所需的复选框

javascript - 简单的算术挑战功能,尝试次数有限

html - 如何根据 HTML 和 CSS 中的百分比创建大小的嵌套框?

reactjs - 无法将函数传递给 props

reactjs - 我可以在不知道 sliced reducer 路径的情况下编写选择器吗?

javascript - 对象默认值?

javascript - Here Maps API - 基本地点显示 (placeId)

javascript - 将点击绑定(bind)到一个div并在React中获取属性数据