16

私は 3 を使用しているアプリを持っていContext Providerます。<App/>アプリが機能するには、これらすべてをラップ する必要がありますproviders。アプリが成長するにつれて、接続する必要があるデータの種類が増えるためのプロバイダーがいくつか増えることを期待しています。プロバイダーを に渡すためのより良い方法があるかもしれないと、私はすでに感じ始めています<App />

私のApp.jsコード:

import React from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import { Provider as BlogProvider} from './src/context/BlogContext';
import { Provider as VehicleProvider} from './src/context/VehicleContext';
import { Provider as AuthProvider} from './src/context/AuthContext';

import IndexScreen from './src/screens/IndexScreen';
import ShowScreen from './src/screens/ShowScreen';
import CreateScreen from './src/screens/CreateScreen';
import EditScreen from './src/screens/EditScreen';
import VehicleScreen from './src/screens/VehicleScreen';

const navigator = createStackNavigator(
  {
    Index: IndexScreen,
    Show: ShowScreen,
    Create: CreateScreen,
    Edit: EditScreen,
    Debug: DebugScreen,
    Vehicle: VehicleScreen,

  },
  {
    initialRouteName: 'Index',
    defaultNavigationOptions: {
      title: 'Main'
    }
  }
);

const App = createAppContainer(navigator);

export default () => {
  return (
    <BlogProvider>
      <VehicleProvider>
        <AuthProvider>
             <App />
        </AuthProvider>
      </VehicleProvider>
    </BlogProvider>
  );
};

私が持っている質問のいくつかは次のとおりです。

  1. アプリで複数のコンテキスト プロバイダーを使用するより良い方法はありますか。
  2. これらのプロバイダーが入れ子になっている順序は、アプリに影響を与えますか?
  3. プロバイダーの追加をスキップして<App/>、代わりに必要な任意の画面にプロバイダーをインポートし、その画面要素をラップすることはできますか?
4

4 に答える 4

10

聞かれたからには答えません。

答え 3

プロバイダーが特定のコンポーネントのコンテキストのみを提供する場合は、それをインポートしてそのコンポーネントで使用する必要があります。ラップしないAppでください。

その理由は、プロバイダーが更新されるたびに、すべてのコンシューマーが再レンダリングされるため、それを使用または停止することはできませReact.memoん。コンテキストを過度に使用しないでくださいReactPureComponentshouldComponentUpdate

const Root = () => {
  return (
    <AppProvider>
      <ComponentProvider>
        <App/>
      <ComponentProvider>
    </AppProvider>
  )
}

const App = () => {
  return (
    <>
      <ComponentA/>
      <ComponentB/>
    <>
  )
}

const ComponentContext = createContext()
const ComponentProvider = ({ children }) => {
  // If any value here is updated --> all consumer will be render
  // --> App re-render --> ComponentA and ComponentB re-render
  return (
    <ComponentContext.Provider value={{ value1, value2, value }}>
      {children}
    </ComponentContext.Provider>
  )
}

代わりにこれを行う必要があります

const Root = () => {
  <AppProvider>
    <App/>
  </AppProvider>
}

const App = () => {
  return (
   <>
    <ComponentA/>
    <ComponentB/>
   <>
  )
}

const ComponentA = () => {
  return (
    <ComponentProvider>
      <OtherComponent/>
    <ComponentProvider>
   )
}

const ComponentContext = createContext()
const ComponentProvider = ({ children }) => {
  // If any value here is updated --> all consumer (ComponentA only) will be render
  return (
    <ComponentContext.Provider value={{ value1, value2, value3 }}>
      {children}
    </ComponenContext.Provider>
  )
}

答え 1

回答 3 は、適切な場所でコンテキストを使用するための答えになる可能性があります (コンテキストのみを消費するコンポーネントの場合。アプリ レベルですべてのコンテキストをランダムにしないでください)。コンテキストが頻繁に更新される場合は、他の方法を使用しないことをお勧めします。これにより、React.memoまたはPureComponentまたはshouldComponentUpdate不要な再レンダリングを使用してパフォーマンスを最適化できます。

答え 2

注文はアプリには影響しません。

于 2020-06-30T04:00:04.050 に答える
0
  1. アプリで複数のコンテキスト プロバイダーを使用するより良い方法はありますか。

答え: はい

  • Context Providersをラップするために任意の番号を使用できますがApp、それらのデータはProviders頻繁に更新されるべきではなく、アプリのどこからでもアクセスされるか、アクセスされることを意味するグローバル状態として扱われるようにしてください。例: アプリのテーマ、認証ステータス、ユーザーのプロフィールなど
  • データが特定のユースケースとAppContext Providerなされ、.それのようにReact.memoこれを参照してください
  1. これらのプロバイダーが入れ子になっている順序は、アプリに影響を与えますか?

答え: はい

  • 回答 1 で述べたように、Provider頻繁に更新されるデータが更新頻度の低いデータの親である場合、そのすべての子に影響を与えるため、最も更新頻度の低いデータを親としてラップすることでリファクタリングできます。
  1. プロバイダーの追加をスキップして、代わりに必要な任意の画面にプロバイダーをインポートし、その画面要素をラップすることはできますか?

回答: ユースケース次第です。

于 2020-07-02T08:13:34.487 に答える