How to sync Redux state and url hash tag params

做~自己de王妃 提交于 2019-11-27 10:02:45
Dan Abramov

I think you don’t need to.
(Sorry for a dismissive answer but it’s the best solution in my experience.)

Store is the source of truth for your data. This is fine.
If you use React Router, let it be the source of truth for your URL state.
You don’t have to keep everything in the store.

For example, considering your use case:

Because the url parameters only contain the slugs of the lectures and the chapters which are selected. In the store I have a list of lectures and chapters with a name, slug and a selected Boolean value.

The problem is you’re duplicating the data. The data in the store (chapter.selected) is duplicated in the React Router state. One solution would be syncing them, but this quickly gets complex. Why not just let React Router be the source of truth for selected chapters?

Your store state would then look like (simplified):

{
  // 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!'
    }
  }
}

That’s it! Don’t store selected there. Instead let React Router handle it. In your route handler, write something like

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)

react-router-redux can help you inject the url stuff to store, so every time hash tag changed, store also.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!