React Native:使用useCallback

时间:2019-11-19 09:07:29

标签: reactjs react-native react-hooks react-native-flatlist

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

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

它会增强小组成员的表现吗? 任何其他优化平台清单的建议也将不胜感激。


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

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 个答案:

答案 0 :(得分:1)

useCallback()钩子仅在需要将其作为道具传递到某个已记忆/纯组件中时才保留用于回调的相同引用。如果仅在每个渲染器上调用函数,则没有必要用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>
  );
};