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

React列表选中项全量重渲染,求移动端性能优化方案

优化方案:阻止OrderRule列表全量重渲染

针对你遇到的选中项时列表全量重渲染的问题,以下是具体优化步骤:

1. 用React.memo缓存列表项组件

React.memo会对组件props做浅比较,只有当props真正变化时才触发重渲染。大部分OrderRule项的props在选中状态切换时不会改变,只有选中项的selected属性会变化,这个缓存能直接生效。

修改OrderRule组件:

import { memo } from 'react';

const OrderRule = memo((props) => {
  const rule = props.data;
  // 直接通过props判断选中状态,移除内部维护的state
  const isSelected = props.selected === rule?.Oid;

  return (
    <div 
      onClick={() => props.setSelectedRule(rule?.Oid)}
      className={isSelected ? 'your-selected-class' : ''}
    >
      {/* ...otherStuff */}
    </div>
  );
});

export default OrderRule;

2. 用useCallback固定回调函数引用

父组件中的setSelectedRule每次渲染都会生成新函数,导致子组件props变化触发重渲染。用useCallback固定函数引用,避免不必要的props更新:

修改RulePage代码:

import { useState, useCallback } from 'react';

const RulePage = () => {
  const [rules, setRules] = useState([]);
  const [selected, setSelected] = useState(null);

  // useCallback包裹,依赖项留空(setSelected是React稳定的state setter,无需加入依赖)
  const setSelectedRule = useCallback((oid) => {
    setSelected(oid);
  }, []);

  return (
    rules && <OrderRuleList 
      selected={selected} 
      setSelectedRule={setSelectedRule} 
      rules={rules} 
      {...aLotOfProps}
    />
  );
};

同时简化OrderRuleList,直接传递父组件的回调,避免额外包装函数引发props变化,并且给列表组件也加上React.memo:

import { memo } from 'react';

const OrderRuleList = memo((props) => {
  return (
    props.rules.map((rule) => (
      <OrderRule 
        key={rule.Oid} // 必须用唯一且稳定的标识当key,比如rule的Oid,不能用index
        selected={props.selected} 
        data={rule} 
        setSelectedRule={props.setSelectedRule} 
        {...moreProps}
      />
    ))
  );
});

export default OrderRuleList;

3. 移除列表项内部的selected状态

你之前在OrderRule里用useState维护选中状态,会导致内部状态和外部props不同步,而且完全没必要——直接通过props.selected和当前项的Oid对比就能判断选中状态,既保证状态统一,也避免了内部state带来的额外渲染。

4. 确保循环渲染的key唯一稳定

map渲染列表项时,必须用每个rule的唯一标识(比如Oid)作为key,不能用数组index。index会在列表项顺序变化时失效,导致React无法正确复用组件,反而可能引发更多不必要的重渲染。

为什么之前的useMemo没生效?

大概率是你没正确处理依赖项,或者把useMemo用在了错误的位置(比如包裹整个列表JSX,但回调函数仍每次更新,导致useMemo依赖变化、缓存失效)。上面的方案从根源上解决了props频繁变化的问题,比单纯用useMemo更有效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:06:32