【发布时间】:2021-05-16 23:43:01
【问题描述】:
我遇到了与here 描述的完全相同的问题。使用选项卡或抽屉在屏幕之间导航时,每个屏幕都会重新加载,从而导致我的应用出现问题。
我已尝试遵循线程中给出的一些建议,但我无法将其应用于我的代码。例如:
对我来说,解决方案是将导航器作为屏幕组件的子级嵌套,而不是将导航器插入到组件属性中。
将其包装在文件的顶层并将其分配给一个变量,然后在组件中使用该变量。
我的抽屉由 4 个指向 4 个屏幕(主页、历史记录、组、设置)的快捷方式组成。前三个也可以在主屏幕的底部选项卡中找到。
这是我的代码:
Navigation.js
import React from "react";
import { TouchableOpacity } from "react-native";
import { NavigationContainer} from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { Entypo } from "@expo/vector-icons";
import Settings from "../screens/Settings";
import Loading from "../screens/Loading";
import AddGroup from "../screens/AddGroup";
import GroupList from "../screens/GroupList";
import Home from "../screens/Home";
import Groups from "../screens/Groups";
import History from "../screens/History";
const HomeStack = createStackNavigator();
const HomeStackScreen = ({ route }) => (
<HomeStack.Navigator}>
<HomeStack.Screen
name={route.name}
component={Home}
/>
</HomeStack.Navigator>
);
const HistoryStack = createStackNavigator();
const HistoryStackScreen = ({ route }) => (
<HistoryStack.Navigator>
<HistoryStack.Screen
name={route.name}
component={History}
/>
</HistoryStack.Navigator>
);
const GroupsStack = createStackNavigator();
const GroupsStackScreen = ({ route }) => (
<GroupsStack.Navigator>
<GroupsStack.Screen
name={route.name}
component={Groups}
/>
</GroupsStack.Navigator>
);
const AppTabs = createBottomTabNavigator();
const bottomTabsScreen = ({ route }) => (
<AppTabs.Navigator>
<AppTabs.Screen
name="Home"
component={HomeStackScreen}
/>
<AppTabs.Screen
name="History"
component={HistoryStackScreen}
/>
<AppTabs.Screen
name="Groups"
component={GroupsStackScreen}
/>
</AppTabs.Navigator>
);
const AppDrawer = createDrawerNavigator();
const AppDrawerScreen = ({ navigation }) => (
<AppDrawer.Navigator>
<AppDrawer.Screen name="Home" component={bottomTabsScreen} />
<AppDrawer.Screen name="History" component={HistoryStackScreen} />
<AppDrawer.Screen name="Groups" component={GroupsStackScreen} />
<AppDrawer.Screen name="Settings" component={Settings} />
</AppDrawer.Navigator>
);
const RootStack = createStackNavigator();
const RootStackScreen = () => {
const [isLoading, setIsLoading] = React.useState(true);
React.useEffect(() => {
setTimeout(() => {
setIsLoading(!isLoading);
}, 500);
}, []);
return (
<RootStack.Navigator mode="modal">
{isLoading ? (
<RootStack.Screen name="Loading" component={Loading} />
) : (
<RootStack.Screen
name="AppDrawerScreen"
component={AppDrawerScreen}
/>
)}
<RootStack.Screen
name="AddGroup"
component={AddGroup}
options={modalOptionStyle}
/>
<RootStack.Screen
name="GroupList"
component={GroupList}
options={({ navigation }) => ({
headerTitle: "Select an existing group",
})}
/>
</RootStack.Navigator>
);
};
export default () => {
return (
<NavigationContainer>
<RootStackScreen />
</NavigationContainer>
);
};
index.js:
import React from "react";
import Navigation from "./config/Navigation";
import { ConversionContextProvider } from "./util/ConversionContext";
export default () => (
<ConversionContextProvider>
<Navigation />
</ConversionContextProvider>
);
遵循 x00 建议后的最终工作代码:
useEffect(() => {
if (isFocusedGroups) setLoading(true);
const unsubscribe = navigation.addListener("focus", () => {
loadFlatlist("groups")
.then()
.catch((error) => console.error(error))
.finally(() => {
setLoading(false);
});
});
return unsubscribe;
}, [navigation, isFocusedGroups]);
【问题讨论】:
-
您的代码有错误。一方面:
modalOptionStyle未定义。可能没关系,但掩盖了你的问题。AppDrawerScreen中的navigation道具也是如此,您实际上并未使用。等等。请消除噪音并制作一个最小可重现的例子(你很有可能在这个过程中自己解决你的问题)。此外,您应该显示一些屏幕的代码和导航方式。内联函数options={({ navigation }) => ({ headerTitle: "Select an existing group" })}也可能导致一些重新渲染,但可能仅适用于GroupList。无论如何,我们需要更多代码 -
我创建了一个 repro here,我将在今天晚些时候尝试用最少的代码清理它。在 History 和 Groups 选项卡之间切换时,您可以在控制台中看到 "LOADING FLATLIST (loadFlatlist) FOR: savedRuns" 每次执行。我认为这是问题的根本原因。
标签: react-native react-navigation