You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FlatList在Axios请求新数据后未重新渲染的问题排查

问题描述

实现MyList组件,根据传入的date参数通过Axios请求接口数据,使用FlatList渲染内容。当父组件更新date并传递给MyList后,接口返回新数据且list状态已更新,但FlatList未重新渲染展示变化后的内容。已配置extraData={list},问题依旧。

注意:两次请求返回的数组元素数量、_id、name完全一致,仅somelist字段的值存在差异。

相关代码

MyList组件

const MyList = ({ date }) => {
    const [list, setList] = useState([]);

    useEffect(() => {
        const url = `https://some-service.com/list?date=${date}`;
        axios.get(url).then((res) => {
            setList(res.data.result);
        });
    }, [date]);

    return (
        <FlatList
            data={list}
            extraData={list}
            renderItem={({ item }) => (<RenderItem item={item} />)}
            keyExtractor={(item) => item._id}
        />
    );
};

父组件

//...其他代码...//
const [date, setDate] = useState(moment().format('YYYY-MM-DD'));

return (
    <View style={styles.container}>
        <View style={styles.dateSelector}>
            <DateSelector date={date} setDate={setDate} />
        </View>
        <MyList date={date} />
    </View>
);

接口返回示例

日期2022-12-04的返回

{
    "status": "Success",
    "result": [
        {
            "_id": "638b3ddc1b11677f6202eb4c",
            "name": "John Doe",
            "somelist": [
                {
                    "date": "2022-12-04T00:00:00.000Z",
                    "status": "good"
                }
            ]
        },
        {
            "_id": "638b3ddc1b11677f6202eb4f",
            "name": "Pappu",
            "somelist": [
                {
                    "date": "2022-12-04T00:00:00.000Z",
                    "status": "bla"
                }
            ]
        }
        // ...更多数据
    ]
}

日期2022-12-03的返回

{
    "status": "Success",
    "result": [
        {
            "_id": "638b3ddc1b11677f6202eb4c",
            "name": "John Doe",
            "somelist": [
                {
                    "date": "2022-12-03T00:00:00.000Z",
                    "status": "bad"
                }
            ]
        },
        {
            "_id": "638b3ddc1b11677f6202eb4f",
            "name": "Pappu",
            "somelist": [
                {
                    "date": "2022-12-04T00:00:00.000Z",
                    "status": "good"
                }
             ]
        }
        // ...更多数据
    ]
}
问题原因
  1. FlatList复用机制:FlatList通过keyExtractor生成的唯一key识别列表项,两次请求返回的列表项_id相同,FlatList会复用原有组件实例,不会触发重新渲染。
  2. 浅比较限制:若RenderItem是用React.memo包裹的纯组件,React默认浅比较仅对比item的顶层属性(_id、name),不会深入嵌套的somelist字段,无法感知其变化。
  3. extraData局限性:虽配置extraData={list}让FlatList感知到数据集合变化,但子组件未正确响应嵌套数据更新时,仍无法触发渲染。
解决方案

方案1:修改keyExtractor,加入date标识

将date与_id组合作为唯一key,让FlatList识别为新列表项:

keyExtractor={(item) => `${item._id}-${date}`}

方案2:让RenderItem正确响应嵌套数据变化

若RenderItem使用React.memo,自定义比较函数实现深比较:

// 可使用lodash的isEqual,或自行实现深比较
import { isEqual } from 'lodash';

const RenderItem = React.memo(({ item }) => {
    // 组件渲染逻辑
}, (prevProps, nextProps) => {
    // 深比较item是否完全一致,不一致则重新渲染
    return isEqual(prevProps.item, nextProps.item);
});

若不想引入lodash,可针对somelist关键字段做针对性比较:

const RenderItem = React.memo(({ item }) => {
    // 组件渲染逻辑
}, (prevProps, nextProps) => {
    const prevSublist = prevProps.item.somelist[0];
    const nextSublist = nextProps.item.somelist[0];
    return prevSublist.date === nextSublist.date && prevSublist.status === nextSublist.status;
});

方案3:强制更新列表引用

设置list时通过展开运算符生成新数组,确保引用变化:

setList([...res.data.result]);

方案4:扩展extraData的依赖

将date也加入extraData,让FlatList更明确感知到依赖变化:

extraData={{ list, date }}

内容的提问来源于stack exchange,提问作者UTKARSH DEEPAK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:10:50