3 Context Provider
を使用しているアプリがあります。アプリが機能するためには、これらすべてのproviders
に<App/>
をラップする必要があります。アプリが成長するにつれ、接続する必要のあるより多くの種類のデータを提供するプロバイダーがいくつか追加されることを期待しています。私はすでにプロバイダーを<App />
に渡すより良い方法があるかもしれないと感じ始めました。
My 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>
);
};
私が持っている質問のいくつかは:
<App/>
へのプロバイダーの追加をスキップして、代わりに、必要な任意の画面にプロバイダーをインポートし、その画面要素をラップできますか?頼まれた順序ではお答えしません。
回答3
プロバイダーが特定のコンポーネントのコンテキストのみを提供する場合は、そのコンポーネントにインポートして使用する必要があります。 しないでくださいApp
で囲みます。
その理由は、プロバイダーが更新されるたびに、すべてのコンシューマーが再レンダリングされるため、使用できないことですReact.memo
またはReactPureComponent
またはshouldComponentUpdate
で停止します。 コンテキストを使いすぎないでください
const Root =() =>{
return(
<AppProvider>
<ComponenAtProvider>
<App/>
<ComponenAtProvider>
</AppProvider>
)
}
const App =() =>{
return(
<>
<ComponentA/>
<ComponentB/>
<>
)
}
const ComponenAContext = createContext()
const ComponenAtProvider = ({children}) =>{
// If any value here is updated ==> all consumer will be render
// ==> App re-render ==> ComponentA and ComponentB re-render
return(
<ComponenAContext.Provider value={{value1, value2, valu3}}>
{children}
</ComponenAContext.Provider>
)
}
代わりにこれを行う必要があります
const Root =() =>{
<AppProvider>
<App/>
</AppProvider>
}
const App =() =>{
return(
<>
<ComponentA/>
<ComponentB/>
<>
)
}
const ComponentA = () =>{
return(
<ComponenAtProvider>
<App/>
<ComponenAtProvider>
)
}
const ComponenAContext = createContext()
const ComponenAtProvider = ({children}) =>{
// If any value here is updated ==> all consumer (ComponentA only) will be render
return(
<ComponenAContext.Provider value={{value1, value2, valu3}}>
{children}
</ComponenAContext.Provider>
)
}
Answer1
答え3はこれに対する答えになる可能性があります。適切な場所でコンテキストを使用します(コンテキストのみを消費するコンポーネントの場合。アプリレベルですべてのコンテキストをランダムにしないでください)。コンテキストが頻繁に更新される場合は、 その他の方法 を使用しないことをお勧めします。これにより、React.memo
またはPureComponent
またはshouldComponentUpdate
は、不要な再レンダリングを防止してパフォーマンスを最適化します。
Answer2
注文はアプリに影響しません
回答1:
const UserScreen=()=>(
<UserProvider>
<UserScreen />
<UserProvider />
)
回答2:
ref
を使用する必要があります。このネストされたレベルのプロバイダーでは、forwardRefを使用する必要があります。残りはうまくいきます回答3:
回答:はい
App
を囲むために任意の数Context Providers
を使用できますが、それらのProviders
のデータは頻繁に更新されず、グローバル状態として扱われることを確認してください。アプリ内のどこからでもアクセスできます。例:アプリのテーマ、認証ステータス、ユーザーのプロファイル、...App
のごく一部でのみ使用される特定のユースケースと見なされる場合、Context Provider
を使用しないでください。データが更新されると、すべての子が強制的に再実行されます。 React React.memo
のようなAPIを回避するためのAPIを使用するかどうかに関係なく、レンダリングします。 this を参照してください。回答:はい
Provider
にあり、更新頻度が低いデータの親である場合、すべての子に影響を与えるため、最も更新されていない最外部を次のようにラップしてリファクタリングできます。親。回答:ユースケース次第です。