React Native:使用 useCallback 优化 flatlist 渲染项

IT技术 reactjs react-native react-hooks react-native-flatlist
2021-05-18 18:06:31

我试图找出尽可能多的方法来优化 flatlist,因为我的 flatlist 组件抱怨我的 flatlist 项目需要太长时间来呈现(我已经在使用 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>
  );
};

它会增强 flatlist 的性能吗?任何其他优化 flatlist 的建议也将不胜感激。


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

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>;
}
1个回答

useCallback()当您需要将它作为props传递给某个记忆化/纯组件时,hook 只是为回调保留相同的 ref。如果您只是在每次渲染时调用函数 - 用useCallback().

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

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>
  );
};