如何同步 Redux 状态和 url 哈希标签参数

IT技术 javascript reactjs react-router redux react-router-redux
2021-03-07 16:00:34

我们有一个讲座和章节列表,用户可以在其中选择和取消选择它们。这两个列表存储在一个 redux 存储中。现在我们希望在 url 的哈希标签中保留所选讲座 slug 和章节 slug 的表示,对 url 的任何更改也应该更改存储(双向同步)。

使用react-router甚至react-router-redux的最佳解决方案是什么

我们真的找不到一些好的例子,其中 react 路由器仅用于维护 url 的哈希标签,并且只更新一个组件。

2个回答

我认为你不需要。
(对不起,我的回答不屑一顾,但这是我经验中最好的解决方案。)

Store 是您数据的真实来源。这可以。
如果你使用 React Router,让它成为你 URL 状态的真实来源。
你不必把所有东西都放在商店里。

例如,考虑您的用例:

因为url参数只包含讲座的slug和选择的章节。在商店中,我有一个讲座和章节列表,其中包含名称、slug 和选定的布尔值。

问题是您正在复制数据。store ( chapter.selected) 中的数据在React Router 状态中被复制。一种解决方案是同步它们,但这很快就会变得复杂。为什么不让 React Router 成为所选章节的真实来源?

您的商店状态将如下所示(简化):

{
  // Might be paginated, kept inside a "book", etc:
  visibleChapterSlugs: ['intro', 'wow', 'ending'],

  // A simple ID dictionary:
  chaptersBySlug: {
    'intro': {
      slug: 'intro',
      title: 'Introduction'
    },
    'wow': {
      slug: 'wow',
      title: 'All the things'
    },
    'ending': {
      slug: 'ending',
      title: 'The End!'
    }
  }
}

而已!不要存放selected在那里。而是让 React Router 处理它。在你的路由处理程序中,写一些类似的东西

function ChapterList({ chapters }) {
  return (
    <div>
      {chapters.map(chapter => <Chapter chapter={chapter} key={chapter.slug} />)}
    </div>
  )
}

const mapStateToProps = (state, ownProps) => {
  // Use props injected by React Router:
  const selectedSlugs = ownProps.params.selectedSlugs.split(';')

  // Use both state and this information to generate final props:
  const chapters = state.visibleChapterSlugs.map(slug => {
    return Object.assign({
      isSelected: selectedSlugs.indexOf(slug) > -1,
    }, state.chaptersBySlug[slug])
  })

  return { chapters }
}

export default connect(mapStateToProps)(ChapterList)
嘿丹。感谢 Redux!我的我也把我的 2 美分放在这个话题上并提出一个问题。如果应用程序状态转换逻辑依赖于查询中的数据怎么办?这意味着减速器需要它,你不能在商店里把它扔掉。
2021-04-22 16:00:34
@AlexanderReshytko 由于这些数据来自“外部世界”,我会在必要时用它发出动作但这并不意味着您需要一个通用的“路由更改”操作(即使您可以在发现它有用时调度它)。然后你的减速器可以使用这些信息,就像他们通常做的那样。
2021-05-02 16:00:34
我会在动作创建者中调用browserHistory.push()browserHistory哪里导入react-router)。我可能会使用 Redux Thunk 来说明存在副作用。我会dispatch({ ... }); browserHistory.push(...)在里面打电话
2021-05-05 16:00:34
很抱歉这么晚才回来,但上周我在度假。我有一个问题。您描述了一种从 url 获取数据并呈现它的方法。您将如何使用新选择的章节更新 url?
2021-05-10 16:00:34
发送参数来重新选择选择器有点笨拙,因此能够从商店获取当前 url 参数非常有用。
2021-05-14 16:00:34

react-router-redux 可以帮助您注入要存储的 url 内容,因此每次哈希标记更改时,也要存储。

它只是给你位置,而不是解析的参数,所以它的用处有限,除非你可以手动重新实现 React Router 给你的东西。这是一个很好的解决方案,可以使存储与操作保持同步,以便记录和重放用户会话工作,但对于不需要它的应用程序来说并不是那么有用。
2021-05-16 16:00:34