问题描述
我试图找出尽可能多的方法来优化 flatlist,因为我的 flatlist 组件抱怨我的 flatlist 项目需要太长时间来呈现(我已经在使用 removeClippedSubviews、windowSize、maxToRenderPerBatch、React.memo 等).
I am trying to figure out as many ways as possible to optimize flatlist since my flatlist component complains my flat list items takes too long to render (I am already using removeClippedSubviews, windowSize, maxToRenderPerBatch, React.memo etc.).
使用 useCallback 包装渲染函数是个好主意吗?
Is it good idea to wrap render function with useCallback?
例如,假设我有一个最初在表单中的函数组件:
For example, lets say I have function component originally in form:
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 包装渲染函数:
If i wrap the render function with useCallback as:
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 的建议也将不胜感激.
Will it enhance the performance of the flatlist?Any other suggestion to optimize flatlist will be appreciated as well.
就安德烈斯所说,我认为通过一些计算实现平面列表项组件的更好方法如下:
So far as Andres says, I think better way to implement flatlist item component with some computation is as follow:
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()
当您需要将回调作为 prop 传递给某个记忆化/纯组件时,钩子只是保持相同的回调引用.如果你只是在每次渲染时调用函数 - 没有必要用 useCallback()
包装它.
useCallback()
hook just keeps the same ref for callback when you need to pass it as a prop into some memoized/pure component. If you just call function on each render - there is no point to wrap it with useCallback()
.
如果这个函数不依赖于其他道具和颜色,你可以从你的组件中提取它并避免在每次渲染时创建函数:
If this function not depends on other props then colors, you can just extract it from your component and avoid of function creation on each render:
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()
来记忆结果:
If you have some heavy computation in your function, it's probably better to use useMemo()
to memoize result:
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>
);
};
这篇关于React Native:使用 useCallback 优化 flatlist 渲染项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!