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

时间:2016-04-19 15:16:29

标签: javascript reactjs react-router redux react-router-redux

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

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

我们无法找到一些很好的例子,其中反应路由器仅用于维护网址的哈希标记,并且只更新一个组件。

感谢!!!

2 个答案:

答案 0 :(得分:143)

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

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

例如,考虑您的使用案例:

  

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

问题是你正在复制数据。存储中的数据(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)

答案 1 :(得分:4)

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