React组件保持以前的状态



我一直在学习ReactReact Native不到一个星期,所以有概念,我仍在学习。下面的代码是第一次尝试编写一个应用程序,通过底部标签导航器导航,更具体地说,使用@react-navigation/material-bottom-tabsreact-native-paper。有三个屏幕,分别是主页、详细信息和帮助。Home和Details都包含一个"请求帮助"按钮,这两个按钮都将重定向到Help屏幕,并作为参数传递一条特殊消息。例如:

<Button
icon="camera"
mode="contained"
onPress={() => navigation.navigate("Help", { txt: "Everything is OK!" })}
style={{ marginTop: 16 }}
>
Ask for help
</Button>

加载应用程序时,HelpScreeninitialParams={{ txt: "nothing" }}启动,屏幕将显示You said nothing。从HomeScreen,点击按钮重定向到HelpScreenonPress={() => navigation.navigate("Help", { txt: "Everything is OK!" })}。因此屏幕将显示You said Everything is OK!。当移动到另一个屏幕,然后回到HelpScreen使用底部选项卡,我希望HelpScreen重新呈现其原始值。因此,我希望屏幕显示为You said nothing。但是不,它仍然写着You said Everything is OK!。同样的行为发生在DetailsScreen和另一个文本。

HelpScreen函数中,我没有将参数保存到状态。因此,我不期望组件在重新呈现时保留以前的值。那么,为什么组件在重新呈现时不重置为其原始值呢?还是不重新渲染?在这种情况下,你能解释一下原因吗?

代码如下:

import { registerRootComponent } from "expo";
import { NavigationContainer } from "@react-navigation/native";
import { NativeStackScreenProps } from "@react-navigation/native-stack";
import { createMaterialBottomTabNavigator } from "@react-navigation/material-bottom-tabs";
import { View } from "react-native";
import { Button, Text } from "react-native-paper";
import { SafeAreaProvider } from "react-native-safe-area-context";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
type NavigationParamList = {
Home: undefined;
Details: undefined;
Help: { txt: string };
};
type PropsHome = NativeStackScreenProps<NavigationParamList, "Home">;
type PropsDetails = NativeStackScreenProps<NavigationParamList, "Details">;
type PropsHelp = NativeStackScreenProps<NavigationParamList, "Help">;
const Tab = createMaterialBottomTabNavigator<NavigationParamList>();
function HomeScreen({ navigation, route }: PropsHome) {
console.log("HOME");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() =>
navigation.navigate("Help", { txt: "Everything is OK!" })
}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function DetailsScreen({ navigation, route }: PropsDetails) {
console.log("DETAILS");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() => navigation.navigate("Help", { txt: "HELP ME!" })}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function HelpScreen({ route }: PropsHelp) {
console.log("HELP");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Text>You said {route.params.txt}</Text>
</View>
);
}
export default function App() {
return (
<SafeAreaProvider>
<NavigationContainer>
<Tab.Navigator initialRouteName="Home" screenOptions={{}}>
<Tab.Screen
name="Home"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
component={HomeScreen}
/>
<Tab.Screen
name="Details"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="alien-outline"
color={color}
size={26}
/>
),
}}
component={DetailsScreen}
/>
<Tab.Screen
name="Help"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="chat-question-outline"
color={color}
size={26}
/>
),
}}
component={HelpScreen}
initialParams={{ txt: "nothing" }}
/>
</Tab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}
registerRootComponent(App);

注意,我没有使用useState钩子。我明白,当一个人想要保留一个值,而不是重置它时,这个钩子是需要的。

React Navigation避免重新渲染每个屏幕,每次都集中在更好的用户体验和避免不必要的屏幕重新渲染。

您应该覆盖此默认行为,并检测何时重新访问屏幕/聚焦并渲染该屏幕。

它提供了实用钩子来监听屏幕的焦点- https://reactnavigation.org/docs/function-after-focusing-screen/

这里的代码重构有一个解决方案:

import { registerRootComponent } from "expo";
import {useEffect,useState} from "react"
import { NavigationContainer ,useIsFocused} from "@react-navigation/native";
import { NativeStackScreenProps } from "@react-navigation/native-stack";
import { createMaterialBottomTabNavigator } from "@react-navigation/material-bottom-tabs";
import { View } from "react-native";
import { Button, Text } from "react-native-paper";
import { SafeAreaProvider } from "react-native-safe-area-context";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";

type NavigationParamList = {
Home: undefined;
Details: undefined;
Help: { txt: string };
};
type PropsHome = NativeStackScreenProps<NavigationParamList, "Home">;
type PropsDetails = NativeStackScreenProps<NavigationParamList, "Details">;
type PropsHelp = NativeStackScreenProps<NavigationParamList, "Help">;
const Tab = createMaterialBottomTabNavigator();
function HomeScreen({ navigation, route }: PropsHome) {
console.log("HOME");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() =>
navigation.navigate("Help", { txt: "Everything is OK!" })
}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function DetailsScreen({ navigation, route }: PropsDetails) {
console.log("DETAILS");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Button
icon="camera"
mode="contained"
onPress={() => navigation.navigate("Help", { txt: "HELP ME!" })}
style={{ marginTop: 16 }}
>
Ask for help
</Button>
</View>
);
}
function HelpScreen({ route ,navigation}: PropsHelp) {
const [message,setMessage] = useState("")
const isFocused = useIsFocused()
useEffect(()=>{
setMessage(route.params.txt)
return ()=>{
navigation.setParams({txt:"nothing"})
}
},[isFocused])
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Route name: {route.name}</Text>
<Text>You said {message}</Text>
</View>
);
}
export default function App() {
return (
<SafeAreaProvider>
<NavigationContainer>
<Tab.Navigator initialRouteName="Home" screenOptions={{}}>
<Tab.Screen
name="Home"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
component={HomeScreen}
/>
<Tab.Screen
name="Details"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="alien-outline"
color={color}
size={26}
/>
),
}}
component={DetailsScreen}
/>
<Tab.Screen
name="Help"
options={{
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons
name="chat-question-outline"
color={color}
size={26}
/>
),
}}
component={HelpScreen}
initialParams={{ txt: "nothing" }}
/>
</Tab.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}


工作演示- https://snack.expo.dev/@emmbyiringiro/493761

相关内容

  • 没有找到相关文章

最新更新