Reactjs 对路由器位置、分页/排序和获取进行Redux反应

Reactjs 对路由器位置、分页/排序和获取进行Redux反应,reactjs,redux,pagination,redux-saga,query-parameters,Reactjs,Redux,Pagination,Redux Saga,Query Parameters,我正在编写一些通用的Todo列表组件,具有以下特性 分页/排序 在URL中保留部分状态(页面、排序) 使用HTTP请求异步获取数据(使用redux saga) 现在,我正试图找到一种模式,用于“最佳”的redux操作序列,以使其顺利工作 我想要以下行为: 加载Todo组件时:读取URL查询参数并使用此参数获取数据 当用户单击按名称排序(或下一页或按xyz文件管理器)时,应更新URL中的查询参数并提取下一个数据 我当前代码的功能: 我正在react redux的MapStateTrops中

我正在编写一些通用的Todo列表组件,具有以下特性

  • 分页/排序
  • 在URL中保留部分状态(页面、排序)
  • 使用HTTP请求异步获取数据(使用redux saga)
现在,我正试图找到一种模式,用于“最佳”的redux操作序列,以使其顺利工作

我想要以下行为:

  • 加载Todo组件时:读取URL查询参数并使用此参数获取数据

  • 当用户单击
    按名称排序
    (或
    下一页
    按xyz文件管理器
    )时,应更新URL中的查询参数并提取下一个数据

我当前代码的功能:

我正在react redux的
MapStateTrops
中创建道具
todos
pagination
sort

state => {
    todos: state.venues.page,
    pagination: parsePagination(state.router.location.search),
    sorting: parseSorting(state.router.location.search)
}
在组件中,我有生命周期和方法,如:

componentDidMount() {
    // these props come from redux's "mapStateToProps"
    dipatch(executeFetch(this.props.pagination, this.props.sorting));
}

onSortingChange = (sorting) => {
    // this will use connected-react-router's "push"
    // to update the browser's URL
    dispatch(dispatchSetSortingQueryParam(sorting));
}

onPaginationChange = (pagination) => {
    // same as "onSortingChange"
    dispatch(setPaginationQueryParam(sorting));
}
现在是一个大问号:

排序
分页
更改时,应在何处/如何运行
executeFetch

  • componentDidUpdate?这看起来很有希望,但是:它创建了一个无休止的循环,因为每个
    executeFetch
    都会触发一个组件更新,然后组件更新将一次又一次地运行
    componentDidUpdate
    。我可以在这里检查
    分页
    和/或
    排序
    是否已更改,然后运行
    executeFetch
    但每次属性更改时,我都会得到这两个属性的一个新对象实例,这需要进行深入的相等性检查。不太好

  • 在排序更改和分页更改的每个
    末尾添加
    executeFetch
    。这似乎有效,但感觉有点多余。另一个问题是,我无法使用
    this.props.sorting
    this.props.pagination
    来运行
    executeFetch
    ,因为这些道具尚未更新


如何在应用程序中解决此问题?

我认为这就是您描述的场景:

循环要求您执行相等性检查,以仅在特定条件下更新redux状态。这是一个问题,因为组件从url状态和redux状态重新呈现。将该逻辑分为两个部分应该有效:

实际上,这可能看起来像:

let App = () => (
  <Router>
    <>
      <Route component={class extends Component {
        componentDidUpdate() {
          let { pagination, sorting } = parse(window.location.search)
          dipatch(executeFetch(pagination, sorting));
        }
        render() { return null }
      }} />
      <Route path="/todo_list" component={props => (
        <div>
          {/* change url via link */}
          <Link to={...}>Change Page</Link>
          {/* change url programatically */}
          <input
            onChange={e => props.history.push(...)}
          />
        </div>
      )} />
    </>
  </Router>
)
let App=()=>(
(
{/*通过链接更改url*/}
换页
{/*以编程方式更改url*/}
道具。历史。推送(…)}
/>
)} />
)

其中,todolist不发送修改url的操作,而只是使用
组件或
历史。按
添加分页和排序信息。

我想我有一个很好的答案。你带什么东西来了吗?谢谢。我使用的是
connected react路由器
,不过基本上URL应该是redux状态的一部分。这种方法看起来很有趣。但我猜您缺少了最后一部分:组件还将更新URL。当用户单击“下一页”时,URL必须更改。你能为这个用例添加更多的代码吗?只使用链接<代码>
components?我还认为将url状态与redux同步是个坏主意,但这只是我的想法
Link
s不适用于所有场景。例如,我有一些“实时搜索”。当用户在搜索输入框中键入时,URL会自动更改(
todos?page=1&searchQuery=test
)并执行搜索。