web-dev-qa-db-ja.com

Redux状態とURLハッシュタグパラメーターを同期する方法

ユーザーが選択および選択解除できる講義と章のリストがあります。 2つのリストはreduxストアに保存されます。ここで、選択した講義スラッグと章スラッグの表現をURLのハッシュタグに保持し、URLを変更するとストアも変更する必要があります(双方向同期)。

react-router または react-router-redux を使用した場合の最良のソリューションは何でしょうか?

反応するルーターがURLのハッシュタグを維持するためだけに使用され、また1つのコンポーネントのみを更新するという良い例を見つけることができませんでした。

ありがとう!!!

70
JoKer

必要ないと思います.
(却下の答えは申し訳ありませんが、それは私の経験では最良の解決策です。)

ストアはデータの真実の源です。これは大丈夫です。
Reactルーターを使用する場合、それをURL状態の真実のソースにします。
店内にすべてを保管する必要はありません。

たとえば、ユースケースを考えます:

Urlパラメーターには、選択された講義と章のスラッグのみが含まれているためです。ストアには、名前、スラッグ、選択したブール値を含む講義と章のリストがあります。

問題は、データを複製していることです。ストア内のデータ(chapter.selected)は、Reactルーター状態で複製されます。 1つの解決策はそれらを同期することですが、これはすぐに複雑になります。なぜ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ルーターに処理させます。ルートハンドラで、次のように記述します

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)
144
Dan Abramov

react-router-reduxは、保存するURLを挿入するのに役立ちます。したがって、ハッシュタグが変更されるたびに、保存することもできます。

4
David Guan