在 ReactNative 中使用多个上下文提供程序的更好方法

esa*_*wan 15 reactjs react-native react-context react-hooks use-context

我有一个应用程序,我在其中使用 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>
  );
};
Run Code Online (Sandbox Code Playgroud)

我的一些问题是:

  1. 有没有更好的方法在应用程序中使用多个上下文提供程序。
  2. 这些提供程序的嵌套顺序对应用程序有什么影响吗?
  3. 我们可以跳过添加提供程序<App/>,而是将它们导入到任何需要它的屏幕中并将该屏幕元素包装在其中吗?

Ton*_*yen 8

我不会按顺序回答。

答案 3

如果提供者仅为特定组件提供上下文,则应在该组件中导入和使用它。不要App用它包裹。

原因是只要供应商有更新,每一个消费者会重新渲染,你不能没有使用React.memoReactPureComponentshouldComponentUpdate停止它。你不应该过度使用上下文

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>
  )
}
Run Code Online (Sandbox Code Playgroud)

你应该这样做

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>
  )
}
Run Code Online (Sandbox Code Playgroud)

答案 1

答案 3 可以解决这个问题,在正确的位置使用上下文(对于仅使用上下文的组件。不要在应用程序级别随机使用每个上下文)。如果您的上下文经常更新,我建议不要使用其他方式,以便您可以使用React.memoPureComponentshouldComponentUpdate防止不必要的重新渲染以优化性能。

答案 2

该订单不会影响应用程序。