【问题标题】:React Redux with Router Location, Pagination / Sorting and FetchReact Redux 与路由器位置、分页/排序和获取
【发布时间】:2018-08-10 03:00:03
【问题描述】:

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

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

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

我想要以下行为:

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

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

我当前的代码做了什么:

我正在 react-redux 的 mapStateToProps 中创建道具 todospaginationsort

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

现在是个大问号:

sortingpagination 发生变化时,我应该在哪里/如何运行executeFetch

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

  • 在每个onSortingChangeonPaginationChange 的末尾添加executeFetch。这似乎有效,但感觉有点多余。另一个问题是,我不能使用this.props.sortingthis.props.pagination 来运行executeFetch,因为这些道具还没有更新。

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

【问题讨论】:

  • 我想我有一个很好的答案。你有什么东西来了吗?

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


【解决方案1】:

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

循环要求您进行相等性检查以仅在某些条件下更新 redux 状态。这是由一个组件从 both 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>
)

其中todolist不是调度action修改url,而是使用&lt;Link /&gt;组件或history.push添加分页和排序信息。

【讨论】:

  • 谢谢。我正在使用connected-react-router,尽管基本上 URL 应该是 redux 状态的一部分。这种方法看起来很有趣。但我猜你错过了最后一部分:组件也会更新 URL。当用户点击“下一页”时,URL 必须改变。你能为这个用例添加更多代码吗?
  • 只使用链接? &lt;Link /&gt; 组件?
  • 另外我认为将 url 状态与 redux 同步是一个坏主意,但这只是我
  • Links 不适用于所有场景。例如,我有某种“实时搜索”。当用户在搜索输入框中输入内容时,URL 会自动更改 (todos?page=1&amp;searchQuery=test) 并执行搜索。
猜你喜欢
  • 2016-05-23
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
  • 2016-04-28
  • 1970-01-01
相关资源
最近更新 更多