You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Redux源数组修改时所有用户事件行重复渲染?

解决Redux事件更新导致所有用户行重渲染的问题

核心问题分析

当前所有用户行触发重渲染的原因有两点:

  1. 每次事件更新时,全局events数组会生成新引用,导致getEventsByUser selector对所有用户ID重新执行filter操作,返回新的数组引用——即便部分用户的事件内容完全未变化。
  2. EventsRow组件未做纯组件优化,即便props无变化也可能触发重渲染。

解决方案

1. 在Redux State中维护按用户ID分组的事件映射

修改State结构,新增eventsByUserId字段存储按用户ID分组的事件数组,这样只有事件发生变化的用户对应的数组引用会更新,其他用户的数组引用保持不变。

修改Reducer

// 初始State定义
const initialState = {
  events: [] as EventDTO[],
  eventsByUserId: {} as Record<string, EventDTO[]>
};

// extraReducers中的事件处理
extraReducers: (builder) => {
  builder
    .addCase(postEvent.fulfilled, (state, action) => {
      const newEvents = action.payload as EventDTO[];
      // 更新全局事件数组(若仍需全局列表则保留)
      state.events = state.events.concat(newEvents);
      // 更新按用户ID分组的映射(不可变更新)
      newEvents.forEach(event => {
        state.eventsByUserId[event.userId] = [
          ...(state.eventsByUserId[event.userId] || []),
          event
        ];
      });
    })
    // 同理处理删除事件逻辑
    .addCase(deleteEvent.fulfilled, (state, action) => {
      const deletedEventId = action.payload;
      const deletedEvent = state.events.find(e => e.id === deletedEventId);
      if (!deletedEvent) return;
      
      const userId = deletedEvent.userId;
      // 更新全局事件数组
      state.events = state.events.filter(e => e.id !== deletedEventId);
      // 更新分组映射,生成新数组
      state.eventsByUserId[userId] = state.eventsByUserId[userId].filter(e => e.id !== deletedEventId);
    });
}

2. 优化Selector获取分组后的事件

修改getEventsByUser selector,直接从分组映射中获取对应用户的事件,避免全局数组变化时的不必要计算:

export const getEventsByUser = createSelector(
  (state: RootState) => state.schedule.eventsByUserId,
  (_: RootState, userId: string) => userId,
  (eventsByUserId, userId) => eventsByUserId[userId] || []
);

3. 将EventsRow组件改为纯组件

使用React.memo包裹组件,确保只有当user或events的引用变化时才触发重渲染:

import React from 'react';

const EventsRow = React.memo(({ user }: { user: string }) => {
  const events: EventDTO[] = useAppSelector(state => getEventsByUser(state, user));
  
  // 组件渲染逻辑...
});

export default EventsRow;

效果验证

修改后,新增或删除事件时:

  • 仅事件所属用户的eventsByUserId条目会生成新数组引用,触发对应EventsRow组件重渲染。
  • 其他用户的events引用未发生变化,React.memo会阻止不必要的重渲染,大幅提升性能。

内容的提问来源于stack exchange,提问作者Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 15:48:24