1. ホーム
  2. javascript

Reduxの状態とurlハッシュタグのパラメータを同期させる方法

2023-08-10 17:17:55

質問

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

を使用した最良の解決策は何でしょうか? react-router あるいは 反応ルータ-REDUX ?

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

どのように解決するのですか?

必要ないのでは?

(見切り発車的な回答で申し訳ありませんが、私の経験上、これがベストな解決策です)

ストアはデータの真実の源です。これでよいのです。

React Routerを使うなら、URLの状態の真実の源はReact Routerに任せましょう。

すべてをストアに保持する必要はありません。

例えば、ユースケースを考えてみると

URLパラメータは、選択された講義と章のスラッグのみを含むためです。ストアには、名前、スラッグ、および選択されたブール値を持つ講義と章のリストがあります。

問題は、データを重複させていることです。ストアのデータ ( chapter.selected ) のデータは、React Router のステートで重複しています。解決策の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 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)