首页 > 解决方案 > FlatList onPress 函数重新渲染导致 usestate 更新后滞后

问题描述

所以我们有一个包含大约 200/300 个按钮的平面列表。这些按钮通过一个函数在 5 次点击后显示广告。所以我们使用 useState 来统计点击次数。

但是..因为我们更新了函数内部的计数,所以它再次调用它自身,并重新呈现所有平面列表项/按钮并导致滞后/延迟。

“你说的滞后是什么意思?” 例如,通常您可以垃圾邮件单击按钮,一切都很好,但是当 setCount(prev => prev +1)取消注释时,它只会慢慢冻结并落后

代码

import React, {useCallback, useState} from 'react';
import {TouchableOpacity,FlatList, View, Text} from 'react-native';

const data = ['IMAGINE 200 items here.']

const test = () => {
    const [count, setCount] = useState(0);

    const TestFunction = useCallback(async () => {
        setCount(prev => prev + 1);

        if (count === 5) {
            /*for example show a add*/
            showAd();
        }
    }, [count]);


    return (
        <View>
            <FlatList data={data} renderItem={() => React.useMemo(<TouchableOpacity onPress={TestFunction}>
                <Text>Test</Text>
            </TouchableOpacity>)}>

            </FlatList>
        </View>
    );
};


const showAd = () => {
    /*for example show a add*/
};

标签: reactjsreact-nativereact-functional-component

解决方案


我相信你应该把 TestFunction 一分为二

const addClick = useCallback(() => { setCount(prev => prev + 1) }, []) 
// this doesn't need count dependency

const showAdOnCountThreshold = useEffect(() => { if (count === 5) showAd() }, [count] 
// this gets called after updating the count

此外,您React.memo没有做任何事情,因为它没有设置依赖项。但是既然你拥有addClick了永远不会改变的东西,那么 Touchables 就没有理由改变(就道具变化而言)。

所以你可以这样做:

const renderClickCountButton = React.useCallback(() => (
 <TouchableOpacity onPress={addClick}>...</TouchableOpacity>
), [addClick])

接着

<FlatList renderItem={renderClickCountButton}

推荐阅读