问题:我的整个应用程序都有一个上下文,但我需要一个用于单个抽屉屏幕及其子屏幕和组件的附加上下文。
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>
);
};
取决于
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 />
</>
);
}