【问题标题】:How to initiate a data fetch in a paging control (on initial load and when user pages through data)如何在分页控件中启动数据提取(在初始加载和用户通过数据分页时)
【发布时间】:2023-11-10 20:54:01
【问题描述】:

在带有 react、redux 和 redux saga 的应用中,哪里是放置启动数据获取的代码的最佳位置,尤其是在包含分页的组件中(并且当前页面的数据缓存在存储并且仅在尚未缓存时才应获取)?

我可以从this question 看到一个建议是在组件本身中执行此操作(例如在componentDidMount 中),这就是我所做的(除了我使用了使用useEffect 的功能组件钩子代替),但逻辑现在分布在几个地方,看起来并不干净。

假设用户单击某个链接将他们带到某个地方(例如使用 react-router),该链接加载了一个显示用户列表的组件。发生这种情况时,我们希望启动用户获取,并显示一些进度(例如微调器),直到数据可用。当用户单击分页控件以获取下一页用户等时,我们也希望发生同样的事情。

这是我目前拥有的,我认为不太正确:

  • 初始人口...
    • Users(功能性)组件加载。
    • 这会接收 page(当前页面的索引)和 users(要显示的用户数组:最初为 null)的 props。
    • 它使用useEffect 挂钩来执行启动提取的副作用。即它发送一个 USERS_FETCH_REQUESTED 动作。
    • 这是由 saga 处理的,最终会以 USERS_FETCH_SUCCESSUSERS_FETCH_ERROR 响应。
    • 这将导致组件被重新渲染,这次填充了 users 数组。
  • 分页...
    • Users 组件呈现分页控件(用于转到下一页、最后一页等的按钮)。
    • 这些按钮调用传递给 props 的 setPage 函数,以处理页面更改。
    • 这会将SET_PAGE 操作分派到商店。
    • reducer 然后更改应用程序状态下的page 值。
    • 这会导致Users 组件的重新渲染。
    • 重新渲染时,因为它使用useEffect 钩子,并且它具有page 作为依赖项,所以它将像以前一样启动获取请求。

以上所有方法都有效,但可能看起来有点混乱,因为 UI 组件负责导致数据获取发生。此外,调用setPage 操作在其中没有任何内容可以启动用户获取,但在逻辑上可能应该这样做。但是,如果我们确实将这个逻辑放在那个动作中,那么当这个不是由页面更改引起的时候,我们如何让初始加载发生。

需要注意的重要一点是,我们并不总是想在组件加载时获取数据:我们只想在应用程序在商店中的状态还没有的情况下这样做包含当前页面的用户。例如如果加载了用户的第 1 页,则用户导航到应用程序中的其他位置,然后返回到该组件:该组件应该只显示已缓存在商店中的用户。

以下是当前方法下代码的大致样子:

const Users: React.FC<{
    page: number,
    users: User[] | null,
    isFetching: boolean,
    fetchError?: Error,
    setPage: (page: number) => void,
    fetchUsers: (page: number) => void
}> = ({page, users, isFetching, fetchError, setPage, fetchUsers}): JSX.Element => {

    useEffect(() => {
        // Fetch users if we don't already have them in the props.
        !users && fetchUsers(page)
    }, [users, page, fetchUsers])

    return (
        <div>
            <button id="previousPageButton" onClick={() => setPage(page - 1)}>&lt;</button>
            <button id="nextPageButton" onClick={() => setPage(page + 1)}>&gt;</button>
            {fetchError
                ? <div>Error fetching users: {fetchError.message}</div>
                : (isFetching || !users
                    ? <div>Fetching...</div>
                    : users.map(user => <UserRow user={user} key={user.id}/>))

【问题讨论】:

    标签: reactjs redux react-redux redux-saga


    【解决方案1】:

    清理方法的最佳方法是将较低级别的组件连接到 redux 存储。我建议在这里有两个组件:

    1. 用户组件 - 显示您要显示的列表
    2. 页面导航组件 - 显示页面导航按钮

    如果你有存储在redux state中的页码,以及需要显示的User信息列表,那么你可以将User组件和页码组件分别连接到state。

    这样Users组件的mapStateToProps,只会寻找要显示的列表,而Page组件的mapStateToProps只会寻找页码。当您更改页码时,Page 组件将触发两个事件 - 一个更改处于状态的页码,另一个调用挂钩以重新获取要显示的新用户列表。这样,当组件连接到 redux 存储的不同部分时,它们将独立重新渲染。

    【讨论】:

    • 那么我们将初始人口的逻辑放在哪里?在使用 useEffect 钩子的用户组件中,如上面的代码 sn-p 中的?我们如何避免在初始填充和页面更改时获取所需用户的任何逻辑重复?
    最近更新 更多