React Native 应用程序中的重新渲染过多,我该怎么办?
Too many re-renders in react native app, what can I do?
我有一个带有 expo-client 的 React Native 应用程序并给出了太多的重新渲染错误我将 post 文件,请注意我使用 react-native-paper.
这是 App.js,它是应用的包装器
import React from "react";
import { Provider as PaperProvider, DefaultTheme } from "react-native-paper";
import { StatusBar } from "expo-status-bar";
import Homescreen from "./views/screens/homescreen";
//import { SafeAreaView, Text } from "react-native";
export default function App() {
return (
<PaperProvider theme={theme}>
<Homescreen />
<StatusBar />
</PaperProvider>
);
}
const theme = {
...DefaultTheme,
};
这是主屏幕,它是登录和注册组件的包装器
import React from "react";
import { View } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import SignUp from "../components/signup";
import Login from "../components/login";
import { Button } from "react-native-paper";
export default function Homescreen({ navigation }) {
const Stack = createStackNavigator();
return (
<View>
<Button onPress={() => navigation.navigate("SignUp")}>SignUp</Button>
<Button onPress={() => navigation.navigate("LogIn")}>Login</Button>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="SignUp" component={SignUp} />
<Stack.Screen name="LogIn" component={Login} />
</Stack.Navigator>
</NavigationContainer>
</View>
);
}
有非常相同的注册和登录组件
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function SignUp() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const signUp = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode="outlined"
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode="outlined"
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={signUp(email, password)}
>
Join us now
</Button>
</View>
);
}
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const logIn = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode={outlined}
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode={outlined}
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={logIn(email, password)}
></Button>
</View>
);
}
这是应用栏组件
import React from "react";
import { View } from "react-native";
import { Appbar } from "react-native-paper";
export default function CustomAppBar() {
return (
<View>
<Appbar>
<Appbar.Header>
<Appbar.Content title="Date Planner" />
</Appbar.Header>
</Appbar>
</View>
);
}
<Button>
中的 onClick
事件是问题所在。它会在每次渲染时调用 signUp(email, password)
,这会导致无限循环,因为内部会调用 setPassword
。相反,在 onClick
中,您可以传递回调,请参阅下面我的建议。
您需要将按钮修改为:
<Button
icon="arrow-right-alt"
mode="contained"
onClick={() => signUp(email, password)}
>
Join us now
</Button>
这样,signUp
函数将仅在单击事件时被调用。
根据评论也需要更改 onClick={logIn(email, password)}
以及与上面建议的类似。
我有一个带有 expo-client 的 React Native 应用程序并给出了太多的重新渲染错误我将 post 文件,请注意我使用 react-native-paper.
这是 App.js,它是应用的包装器
import React from "react";
import { Provider as PaperProvider, DefaultTheme } from "react-native-paper";
import { StatusBar } from "expo-status-bar";
import Homescreen from "./views/screens/homescreen";
//import { SafeAreaView, Text } from "react-native";
export default function App() {
return (
<PaperProvider theme={theme}>
<Homescreen />
<StatusBar />
</PaperProvider>
);
}
const theme = {
...DefaultTheme,
};
这是主屏幕,它是登录和注册组件的包装器
import React from "react";
import { View } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import SignUp from "../components/signup";
import Login from "../components/login";
import { Button } from "react-native-paper";
export default function Homescreen({ navigation }) {
const Stack = createStackNavigator();
return (
<View>
<Button onPress={() => navigation.navigate("SignUp")}>SignUp</Button>
<Button onPress={() => navigation.navigate("LogIn")}>Login</Button>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="SignUp" component={SignUp} />
<Stack.Screen name="LogIn" component={Login} />
</Stack.Navigator>
</NavigationContainer>
</View>
);
}
有非常相同的注册和登录组件
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function SignUp() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const signUp = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode="outlined"
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode="outlined"
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={signUp(email, password)}
>
Join us now
</Button>
</View>
);
}
import React, { useState } from "react";
import { View } from "react-native";
import { TextInput, Button } from "react-native-paper";
export default function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const logIn = (t1, t2) => {
setEmail("");
setPassword("");
};
const changeEmailHandler = (e) => {
setEmail(e.target.value);
};
const changePasswordHandler = (e) => {
setPassword(e.target.value);
};
return (
<View>
<TextInput
mode={outlined}
left
label="email"
placeholder="Enter your email: "
onChangeText={changeEmailHandler}
value={email}
/>
<TextInput
mode={outlined}
left
label="password"
placeholder="Enter your password: "
onChangeText={changePasswordHandler}
value={password}
type="password"
/>
<Button
icon="arrow-right-alt"
mode="contained"
onClick={logIn(email, password)}
></Button>
</View>
);
}
这是应用栏组件
import React from "react";
import { View } from "react-native";
import { Appbar } from "react-native-paper";
export default function CustomAppBar() {
return (
<View>
<Appbar>
<Appbar.Header>
<Appbar.Content title="Date Planner" />
</Appbar.Header>
</Appbar>
</View>
);
}
<Button>
中的 onClick
事件是问题所在。它会在每次渲染时调用 signUp(email, password)
,这会导致无限循环,因为内部会调用 setPassword
。相反,在 onClick
中,您可以传递回调,请参阅下面我的建议。
您需要将按钮修改为:
<Button
icon="arrow-right-alt"
mode="contained"
onClick={() => signUp(email, password)}
>
Join us now
</Button>
这样,signUp
函数将仅在单击事件时被调用。
根据评论也需要更改 onClick={logIn(email, password)}
以及与上面建议的类似。