返回

彻底解决 Ant Design Mobile 中 hooks ListView 长列表二次进入 dataSource 报错

前端

引言

在使用 Ant Design Mobile 的 ListView 组件构建长列表时,我们可能会遇到二次进入页面时 dataSource 报错 dataSource must be the same 的问题。本文将深入探讨这一报错的根源并提供详细的解决方案,确保你的列表视图在每次页面刷新或导航后都能正常运行。

错误原因

当使用 hooks 管理 ListView 的数据源(dataSource)时,如果在组件卸载后再次渲染组件,并使用不同的数据源,就会触发此错误。这是因为 React 组件的 state 在卸载后会被清除,导致二次进入时找不到先前的 dataSource。

解决方案

解决此问题的最佳方法是使用 React 的 useEffect 钩子来管理 ListView 的数据源。useEffect 钩子允许我们在组件挂载和更新时执行副作用,例如获取数据或更新状态。

步骤 1:使用 useEffect 管理数据源

在 ListView 组件中,使用 useEffect 钩子获取数据源并更新组件状态:

import { useEffect, useState } from 'react';

const MyListView = () => {
  const [dataSource, setDataSource] = useState([]);

  useEffect(() => {
    // 从服务器获取数据
    const fetchData = async () => {
      const data = await fetch('/api/data');
      setDataSource(data);
    };

    fetchData();
  }, []); // 空数组表示只在组件挂载时执行一次

  return (
    <ListView
      dataSource={dataSource}
      ...
    />
  );
};

步骤 2:使用 React 键

为 ListView 中的每一项设置唯一的键,以帮助 React 追踪列表项的身份:

<ListView
  dataSource={dataSource}
  renderItem={(item) => <ListItem key={item.id} ... />}
/>

步骤 3:在卸载时清除数据源

在组件卸载时,清除 ListView 的数据源,以防止二次进入时出现错误:

useEffect(() => {
  return () => {
    setDataSource([]);
  };
}, []); // 空数组表示只在组件卸载时执行一次

示例代码

以下是解决 ListView dataSource must be the same 错误的完整示例代码:

import { useEffect, useState } from 'react';

const MyListView = () => {
  const [dataSource, setDataSource] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const data = await fetch('/api/data');
      setDataSource(data);
    };

    fetchData();

    return () => {
      setDataSource([]);
    };
  }, []);

  return (
    <ListView
      dataSource={dataSource}
      renderItem={(item) => <ListItem key={item.id} ... />}
    />
  );
};

结论

通过使用 useEffect 钩子来管理数据源、使用 React 键以及在卸载时清除数据源,我们可以有效地解决 Ant Design Mobile 中 hooks ListView 长列表的二次进入报错问题。遵循本文中的步骤,你就可以构建健壮、高效的列表视图,在不同的页面导航或刷新时保持数据完整性。