web-dev-qa-db-ja.com

多すぎるReactコンテキストプロバイダー

ここで反応し、新しいContext APIに頭を回そうとしました(まだReduxなどを調べていません)。

やらなければならないことの大部分を実行できるようですが、最終的にはたくさんのプロバイダーになり、メインアプリをラップするためのタグがすべて必要になります。

Authのプロバイダー、テーマのプロバイダー、チャットメッセージのプロバイダー(Pusher.com)などがあります。また、Reactを使用することも、ラッパー要素の1つです。

私はこれで終わる必要がありますか?.

<BrowserRouter>
    <AuthProvider>
        <ThemeProvider>
            <ChatProvider>
                <App />
            </ChatProvider>
        </ThemeProvider>
    </AuthProvider>
</BrowserRouter>

それとももっと良い方法がありますか?

14
jonhobbs

免責事項:これを使用したことはありません、調査したところです。

FormidableLabs(彼らは多くの OSSプロジェクト に貢献しています)には、 react-context-composer というプロジェクトがあります

問題は解決したようです。

Reactは新しいContext APIを提案しています。 APIは作成を促進します。このユーティリティコンポーネントは、コンポーネントが複数のコンテキストプロバイダーおよびコンシューマーをレンダリングするときにコードをクリーンに保つのに役立ちます。

1
dance2die

数行のコードで問題が解決します。

import React from "react"
import _ from "lodash"

/**
 * Provided that a list of providers [P1, P2, P3, P4] is passed as props,
 * it renders
 *
 *    <P1>
        <P2>
          <P3>
            <P4>
              {children}
            </P4>
          </P3>
        </P2>
      </P1>
 *
 */

export default function ComposeProviders({ Providers, children }) {
  if (_.isEmpty(Providers)) return children

  return _.reverse(Providers)
    .reduce((acc, Provider) => {
      return <Provider>{acc}</Provider>
    }, children)
}

このための簡単な解決策の1つは、 https://github.com/reduxjs/redux/blob/master/src/compose.js のcompose関数に似たものを使用し、すべてのプロバイダーを組み合わせることです。

provider.js

const Providers = compose(
    AuthProvider,
    ThemeProvider,
    ChatProvider
);

また、私はこのソリューションを使用していませんが、Reactの新しいフック機能を使用すると、コンテキストをレンダリングする代わりに、reactフックを使用して関数定義でそれにアクセスできます。

0
Haswin