如何在分页控件中启动数据提取(在初始加载时以及用户对数据进行分页时)

时间:2019-05-24 11:30:57

标签: reactjs redux react-redux redux-saga

在具有react,redux和redux saga的应用程序中,放置代码的最佳位置是启动数据获取的最佳位置,尤其是在包含分页的组件中(当前页面的数据缓存在其中)存储,并且仅应在尚未缓存的情况下获取)?

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

说用户单击某些链接将其带到某处(例如,使用react-router),该链接会加载显示用户列表的组件。发生这种情况时,我们希望启动用户获取操作,并显示一些进度(例如微调框),直到数据可用为止。当用户单击分页控件以获取用户的下一页等时,我们也希望发生同样的事情。

这是我目前拥有的,我认为这是不对的:

  • 初始人口...
    • Users(功能性)组件已加载。
    • 这将接收page(当前页面的索引)和users(要显示的用户数组:最初为null)的道具。
    • 它使用useEffect钩执行初始化访存的副作用。即它调度了一个USERS_FETCH_REQUESTED动作。
    • 这是由传奇处理的,最终会以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}/>))

1 个答案:

答案 0 :(得分:0)

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

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

如果您将页码存储在redux状态下,并且需要显示用户信息列表,则可以将用户组件和页码组件分别连接到状态。

通过这种方式,Users组件的mapStateToProps仅查找要显示的列表,而Page组件的mapStateToProps仅查找页码。当您更改页码时,Page组件将触发两个事件-一个更改状态下的页码,另一个调用该钩子以重新获取要显示的新用户列表。这样,当组件连接到Redux存储的单独部分时,它们将独立地重新渲染。