React Native:使用 useCallback 优化平面列表渲染项

React Native: optimizing flatlist render item with useCallback

我试图找出尽可能多的方法来优化平面列表,因为我的平面列表组件抱怨我的平面列表项渲染时间太长(我已经在使用 removeClippedSubviews、windowSize、maxToRenderPerBatch、React.memo 等.).

用 useCallback 包装渲染函数是个好主意吗?

例如,假设我的函数组件最初是这样的:

const FlatListItem = ({ color1, color2, color3, color4 }) => {
  function renderViewWithColorLogic(color) {
    // do some computationally heavy process
    // ...

    return <View>{/* some components */}</View>;
  }

  return (
    <View>
      {renderViewWithColorLogic(color1)}
      {renderViewWithColorLogic(color2)}
      {renderViewWithColorLogic(color3)}
      {renderViewWithColorLogic(color4)}
    </View>
  );
};

如果我用 useCallback 包装渲染函数为:

const FlatListItem = ({ color1, color2, color3, color4 }) => {
  function _renderViewWithColorLogic(color) {
    // do some computationally heavy process
    // ...

    return <View>{/* some components */}</View>;
  }
  const renderViewWithColorLogic1 = useCallback(()=>_renderViewWithColorLogic(color1), [color1])
  const renderViewWithColorLogic2 = useCallback(()=>_renderViewWithColorLogic(color2), [color2])
  const renderViewWithColorLogic3 = useCallback(()=>_renderViewWithColorLogic(color3), [color3])
  const renderViewWithColorLogic4 = useCallback(()=>_renderViewWithColorLogic(color4), [color4])

  return (
    <View>
      {renderViewWithColorLogic1()}
      {renderViewWithColorLogic2()}
      {renderViewWithColorLogic3()}
      {renderViewWithColorLogic4()}
    </View>
  );
};

它会提高平面列表的性能吗? 任何其他优化平面列表的建议也将不胜感激。


就 Andres 所说,我认为通过一些计算实现平面列表项组件的更好方法如下:

const FlatListItem = ({ color1, color2, color3, color4 }) => (
  const viewWithColorLogic1 = useMemo(()=>_renderViewWithColorLogic(color1), [color1]);
  const viewWithColorLogic2 = useMemo(()=>_renderViewWithColorLogic(color2), [color2]);
  const viewWithColorLogic3 = useMemo(()=>_renderViewWithColorLogic(color3), [color3]);
  const viewWithColorLogic4 = useMemo(()=>_renderViewWithColorLogic(color4), [color4]);

  return (
    <View>
      {viewWithColorLogic1}
      {viewWithColorLogic2}
      {viewWithColorLogic3}
      {viewWithColorLogic4}
    </View>
  );
);

function renderViewWithColorLogic(color) {
    // do some computationally heavy process
    // ...

    return <View>{/* some components */}</View>;
}

useCallback() hook 只是在你需要将它作为 prop 传递给某些 memoized/pure 组件时保留相同的回调引用。如果您只是在每个渲染器上调用函数 - 没有必要用 useCallback().

包装它

如果这个函数不依赖于其他属性然后颜色,你可以从你的组件中提取它并避免在每次渲染时创建函数:

const FlatListItem = ({ color1, color2, color3, color4 }) => (
    <View>
      {renderViewWithColorLogic(color1)}
      {renderViewWithColorLogic(color2)}
      {renderViewWithColorLogic(color3)}
      {renderViewWithColorLogic(color4)}
    </View>
);

function renderViewWithColorLogic(color) {
    // do some computationally heavy process
    // ...

    return <View>{/* some components */}</View>;
}

如果您的函数中有一些繁重的计算,最好使用 useMemo() 来记忆结果:

const FlatListItem = ({ color1, color2, color3, color4 }) => {
  const viewWithColorLogic1 = useMemo(()=>_renderViewWithColorLogic(color1), [color1]);
  const viewWithColorLogic2 = useMemo(()=>_renderViewWithColorLogic(color2), [color2]);
  const viewWithColorLogic3 = useMemo(()=>_renderViewWithColorLogic(color3), [color3]);
  const viewWithColorLogic4 = useMemo(()=>_renderViewWithColorLogic(color4), [color4]);

  return (
    <View>
      {viewWithColorLogic1}
      {viewWithColorLogic2}
      {viewWithColorLogic3}
      {viewWithColorLogic4}
    </View>
  );
};