React中如何正确使用Memo优化HandsOnTable列渲染性能
解决方案
先解决Hook调用错误
你之前的报错是因为React Hook(如useMemo)必须在函数组件的顶层作用域调用,不能嵌套在getSettings这类普通函数里。这是React Hook的核心规则之一。
选择正确的Memo工具
针对你的场景:
React.memo:用来包裹组件,避免组件在props无变化时重渲染,和你当前列生成的性能问题无关,暂时用不上。useMemo:专门缓存计算开销大的值(数组/对象),只有当依赖项变化时才重新计算,完全匹配你的需求——仅在selectedNode变化时重新生成列配置。useCallback:用来缓存函数引用,如果你需要把某个函数作为依赖传递给其他Hook/组件才用,这里暂不需要额外处理。
优化后的代码示例
// 假设这是你的函数组件 function HotTableComponent({ selectedNode }) { // 假设data是根据selectedNode获取的业务数据(比如从props、useSelector或接口请求) const data = getNodeData(selectedNode); // 用useMemo缓存整个columns数组,仅在selectedNode或data变化时重新生成 const columns = useMemo(() => { return data.map((column) => { // 这里的renderer只会在columns重新生成时创建一次 const renderer = () => { // 你的昂贵格式化逻辑,基于当前column数据 }; return { renderer }; }); }, [selectedNode, data]); // 依赖项:只有选中节点或数据变化时,才重新计算columns // 生成HandsOnTable的配置,直接使用缓存好的columns const tableSettings = { columns: columns }; return <HotTable settings={tableSettings} />; } // 复用的列生成函数(可选,纯函数更易维护) const getTableColumn = (column) => { const renderer = () => { // 昂贵格式化逻辑 }; return { renderer }; };
关键说明
- 避免传递函数给columns:原代码中
getSettings返回columns: getTableColumns,会导致HandsOnTable每次渲染都调用getTableColumns一百多次,每次都创建新的renderer,这是性能开销的核心原因。现在改为提前生成完整的columns数组并缓存,从根源减少重复计算。 - 依赖项的正确性:
useMemo的依赖数组要包含所有影响列生成的变量——这里selectedNode是触发更新的开关,data是列的数据源,两者变化时都需要重新生成列。 - React与Lodash Memo的区别:Lodash的
memoize是基于函数参数缓存结果,适合纯函数的跨调用缓存;而React的useMemo是绑定组件渲染周期,依赖数组变化时才重新计算,更适合组件内部响应状态/ props变化的场景,不会出现对象参数引用导致的缓存失效问题。
内容的提问来源于stack exchange,提问作者user2465134
相关产品推荐
相关产品推荐

