通过路由器位置,分页/排序和提取来对Redux进行反应

时间:2018-08-07 19:34:06

标签: reactjs redux pagination redux-saga query-parameters

我正在写一些具有以下功能的通用Todo-List组件

  • 分页/排序
  • 在URL(页面,排序)中保留部分状态
  • 使用HTTP请求(使用redux-saga)异步获取数据

现在,我正在尝试为“最佳” redux动作序列找到一种模式,以使其正常工作。

我想要以下行为:

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

  • 当用户单击sort by name(或next pagefiler by xyz)时,URL中的查询参数应更新,并应获取下一个数据。

我当前的代码做什么:

我正在react-redux的todos中创建道具paginationsortmapStateToProps

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));
}

现在是大问号:

executeFetchsorting更改时,我应该在哪里运行/ pagination

  • componentDidUpdate吗?看起来很有希望,但是:它创建了一个无限循环,因为每个executeFetch都会触发组件更新,然后更新将再次运行componentDidUpdate然后再次。我可以在此处检查pagination和/或sorting是否已更改,然后运行executeFetch但是每次我都会为这两个道具获得一个新的对象实例任何道具变更,都需要进行深入的平等性检查。不好。

  • 在每个executeFetchonSortingChange的末尾添加onPaginationChange。这似乎可行,但是有点多余。另一个问题是,我无法使用this.props.sortingthis.props.pagination来运行executeFetch,因为这些道具尚未更新。

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

1 个答案:

答案 0 :(得分:1)

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

enter image description here

循环要求您进行相等性检查,以仅在某些条件下更新redux状态。这是由于具有从 both 和url状态以及redux状态重新渲染的组件而造成的。将该逻辑分为两个部分应该起作用:

enter image description here

实际上可能是这样的:

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>
)

待办事项列表不是分派修改URL的操作,而是仅使用<Link />组件或history.push添加分页和排序信息。