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

JoK*_*Ker 72 javascript reactjs react-router redux react-router-redux

我们有一个讲座和章节列表,用户可以在其中选择和取消选择它们.这两个列表存储在redux存储中.现在我们想要在url的hash标签中保留选定的讲座slugs和章节slugs的表示,并且对url的任何更改也应该更改存储(双向同步).

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

我们无法找到一些很好的例子,其中react路由器仅用于维护url的hash标记,并且只更新一个组件.

谢谢!!!

Dan*_*mov 144

我想你不需要.
(对不起,这是一个不屑一顾的答案,但根据我的经验,这是最好的解决方案.)

商店是您数据的真实来源.这可以.
如果您使用React Router,请将其作为URL状态的真实来源.
您不必将所有商品都存放在商店中.

例如,考虑您的用例:

因为url参数只包含讲座的slu and和所选的章节.在商店中,我有一个讲座和章节列表,其中包含名称,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!'
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

而已!不要存放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)
Run Code Online (Sandbox Code Playgroud)

  • 我会在动作创建器中调用`browserHistory.push()`(其中`browserHistory`是从`react-router`导入的).我可能会使用Redux Thunk来说清楚是否会产生副作用.我打电话给`dispatch({...}); browserHistory.push(...)`里面. (9认同)
  • 发送参数以重新选择选择器有点尴尬,因此能够从商店获取当前url参数非常有用. (8认同)
  • 抱歉回来这么晚,但我上周假期.我有一个问题.您描述了一种从URL获取数据并进行渲染的方法.您如何使用新选择的章节更新网址? (4认同)
  • 嘿丹 谢谢Redux!我也把我的2美分放在主题上并提出问题.如果应用程序状态转换逻辑依赖于查询中的数据,该怎么办?这意味着减速器需要它,你不能只是在商店里摆脱它. (2认同)
  • @AlexanderReshytko由于这些数据来自"外部世界",我会在必要时用*发出动作*.这并不意味着您需要一个通用的"路由更改"操作(即使您发现它有用,也可以发送它).然后,您的减速器可以像通常那样使用该信息. (2认同)
  • 您的`mapStateToProps`在返回的props的Chapters属性上创建一个新对象。每当存储中的任何更改更改时,这都会导致组件重新呈现(因为每个redux动作中道具之一更改)。 (2认同)