如何将 Context 用于抽屉屏幕及其子屏幕/组件?

问题描述 投票:0回答:1

问题:我的整个应用程序都有一个上下文,但我需要一个用于单个抽屉屏幕及其子屏幕和组件的附加上下文。

DataProvider
被整个App使用。

我创建了一个仅由“组件”A 使用的上下文,即抽屉导航器中的屏幕 A 及其堆栈导航器中的子屏幕(子屏幕)。

到目前为止已经做了什么:

阅读文档并继续使用两个上下文包装整个应用程序,但考虑到抽屉导航器和屏幕的一个子集实际上需要 AContext,我只需要包装仅需要它的屏幕/组件,以防止不必要的重新渲染对于首先不需要上下文的屏幕和组件。

关于在这种情况下如何进行有什么建议还是可以忽略不计?

这是我的 App.js 代码:

const DrawerNavigator = () => {
  
  return (
    <Drawer.Navigator
      initialRouteName=
      screenOptions={({ navigation }) => ({
        headerTitle: "",
      }
      )}
    >
      <Drawer.Screen
        name="A"
        component={A}
        options={{
          // freezeOnBlur: true,
        }}
      />
      <Drawer.Screen
        name="B"
        component={B}
        options={{
          freezeOnBlur: true,
        }}
      />
      <Drawer.Screen
        name="C"
        component={C}
        options={{
          freezeOnBlur: true,
        }}
      />
    </Drawer.Navigator>
  )
};

export default function App() {
  return (
    <>
      <DataProvider>
        <AProvider>
          <NavigationContainer>
            <Stack.Navigator
              screenOptions={({ navigation }) => ({
                headerTitle: "",
              })}
            >
              <Stack.Screen
                name="HOME"
                component={DrawerNavigator}
                options={{ headerShown: false }}
              />
              <Stack.Screen
                name="ASubScreen"
                component={ASubScreen}
                options={{
              />
              <Stack.Screen
                name="D"
                component={D}
                options={{ headerTitle: "" }}
              />
              <Stack.Screen
                name="E"
                component={E}
                options={{ headerTitle: "" }}
              />Ï
            </Stack.Navigator>
          </NavigationContainer>
          <ConsentModal />
        </AProvider>
      </DataProvider>
      <StatusBar style="dark" />
      <Toast />
    </>
  );
}

这是上下文代码:

import React, { useEffect, useState } from "react";

export const AContext = React.createContext();

export const PayEProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState(null);

  return (
    <AContext.Provider
      value={{
        currentUser,
        setCurrentUser
      }}
    >
      {children}
    </AContext.Provider>
  );
};
javascript reactjs react-navigation react-context
1个回答
0
投票

取决于

AContext
值是什么或
AProvider
提供程序组件需要处理和更新它可能可以忽略不计,但从设计/实现来看,它是 always 限制变量范围的良好编码实践越多越好。换句话说,仅将状态/上下文等提升到应用程序结构所需的高度。

使用 React-Navigation

Screen
组件,我相信您有几个基本选项:

  • 创建一个屏幕组件,用于渲染 Context 提供程序和实际屏幕组件,所有这些都在

    component
    属性上。

    const ASubScreenLayout = (props) => {
      ...
    
      return (
        <AProvider>
          ...
          <ASubScreen {...props} />
          ...
        </AProvider>
      );
    };
    
    export default function App() {
      return (
        <>
          <DataProvider>
            <NavigationContainer>
              <Stack.Navigator
                screenOptions={({ navigation }) => ({
                  headerTitle: "",
                })}
              >
                ...
                <Stack.Screen
                  name="ASubScreen"
                  component={ASubScreenLayout}
                  options={{ ... }}
                />
                ...
              </Stack.Navigator>
            </NavigationContainer>
            <ConsentModal />
          </DataProvider>
    
          <StatusBar style="dark" />
          <Toast />
        </>
      );
    }
    
  • 使用

    children
    render prop 函数,这基本上就是上面内联的解决方案。

    export default function App() {
      return (
        <>
          <DataProvider>
            <NavigationContainer>
              <Stack.Navigator
                screenOptions={({ navigation }) => ({
                  headerTitle: "",
                })}
              >
                ...
                <Stack.Screen
                  name="ASubScreen"
                  options={{ ... }}
                >
                  {(props) => (
                    <AProvider>
                      <ASubScreen {...props} />
                    </AProvider>
                  )}
                </Stack.Screen>
                ...
              </Stack.Navigator>
            </NavigationContainer>
            <ConsentModal />
          </DataProvider>
    
          <StatusBar style="dark" />
          <Toast />
        </>
      );
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.