web-dev-qa-db-ja.com

ReactJS-「グローバル」データを深くネストされた子コンポーネントに渡す方法は?

Reactアプリケーションで「グローバル」データを使用するために、通常どのようにアプローチしますか?

たとえば、ユーザーがアプリにログインしたら、次のデータがあるとします。

user: {
  email: '[email protected]',
  name: 'John Doe'
}

これは、アプリのほとんどすべてのコンポーネントが知りたいデータです。したがって、ログイン状態またはログアウト状態でレンダリングしたり、ログインしている場合はユーザーのメールアドレスを表示したりできます。

私の理解では、子コンポーネントでこのデータにアクセスするReact方法は、トップレベルのコンポーネントがデータを所有し、プロパティを使用して子コンポーネントに渡す方法です。

<App>
  <Page1/>
  <Page2>
    <Widget1/>
    <Widget2 user={user}/>
  </Page2>
</App>

しかし、これは私には扱いにくいようです。それは、必要な子にデータを渡すためだけに、各コンポジットにデータを渡す必要があることを意味するためです。

Reactこのタイプのデータを管理する方法はありますか?

注:この例は非常に単純化されています-私は意図としてコンポジットをまとめて、UI機能全体の実装の詳細を適切に変更できるようにします

[〜#〜] edit [〜#〜]:デフォルトでは calling setState on私のトップレベルコンポーネントはすべての子コンポーネントを再レンダリングします 、そして各子コンポーネントで私が好きなデータ(たとえば、状態や小道具だけでなくグローバルデータ)を使用してレンダリングできます。しかし、人々は特定の子コンポーネントのみにレンダリングする必要があることを通知することをどのように選択していますか?

44
Brad Parks

私はもともとこの質問に答えていたので、React自体はいかなる意味でも「グローバル」データをサポートしていません-それは本当にUIを管理するためのものであり、それです。そうは言っても、グローバルcontextデータへのアクセスをサポートするようになりました このページのこの他の回答で詳しく説明しているように 。このレポ( nstatedcontextは、興味のある人のためにより良い方法でラップしていると思われます。 Kent Doddsによる良い記事がありますcontext apiの進化についてそして、Reactで正式にサポートされるようになりました。

contextアプローチは、真にグローバルなデータにのみ使用してください。データが他のカテゴリに分類される場合、次のようにする必要があります。

  • Facebook自身が独自の Flux ライブラリを使用してこの問題を解決しています。
  • Mobx および Redux はFluxに似ていますが、より人気があるようです。彼らは同じことをしますが、よりクリーンで、より直感的な方法で。

いくつかの歴史のために、この回答の元の編集内容を以下に残します。

古い回答:


https://github.com/dustingetz/react-cursor

この類似ライブラリ:

https://github.com/mquan/cortex

主な注意:Ithinkこれは、 Facebook's Flux 、または同様のもの(上記)の仕事です。データフローが複雑になりすぎると、コールバック以外のコンポーネント間で通信するために別のメカニズムが必要になり、Fluxとそのクローンはそのように見えます。

17
Brad Parks

React Context Property を使用します。これは、グローバルデータセットを明示的に転送せずにチェーンに渡すためのものです。ただし、コンポーネントのライフサイクル機能は複雑になり、リンクしたページで提供されている注意事項に注意してください。

11
Steve Taylor

React Context API を使用して、グローバルデータを深くネストされた子コンポーネントに渡すことができます。 Kent C. Doddsは、Medium Reactの新しいContext API で詳細な記事を書きました。 APIの使用方法をよりよく理解するのに役立ちます。

2
mukeshmandiwal

すべての子を{... restOfProps}でレンダリングすることにより、コンポーネントチェーン全体にデータを渡すだけでは何が問題になりますか?

render(){
  const {propIKnowAbout1, propIKnowAbout2, ...restOfProps} = this.props;
  return <ChildComponent foo={propIKnowAbout1} bar={propIKnowAbout2} {...restOfProps}/>
}
1
BoxerBucks