英文:
How can I find the bad setstate in my code?
问题
我的React Native代码似乎执行正常。但我一直在遇到一个错误的setstate
代码错误。以下是错误信息:
警告: 在呈现不同组件(`Login`)时无法更新组件(`ForwardRef(BaseNavigationContainer)`)。要定位`Login`内的错误`setState()`调用,请按照堆栈跟踪中描述的步骤查找,链接在https://reactjs.org/link/setstate-in-render中描述
>> 在 Login(由 SceneView 创建)
我成功追踪到了可能引发错误的代码行(至少我认为是这样):Login @ Login.js:16
。
可能是这部分代码:
export function Login({ navigation }) {
if (auth.currentUser) {
navigation.navigate("Root");
} else {
onAuthStateChanged(auth, (user) => {
if (user) {
navigation.navigate("Root");
}
});
}
以下是整个组件,似乎包含有问题的setState
部分。我无法弄清楚如何消除这个错误。尽管所有的代码似乎都正常工作...
export function Login({ navigation }) {
if (auth.currentUser) {
navigation.navigate("Root");
} else {
onAuthStateChanged(auth, (user) => {
if (user) {
navigation.navigate("Root");
}
});
}
let [errorMessage, setErrorMessage] = React.useState("");
let [email, setEmail] = React.useState("");
let [password, setPassword] = React.useState("");
let login = () => {
if (email !== "" && password !== "") {
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
navigation.navigate("Home", { user: userCredential.user });
// ...
})
.catch((error) => {
setErrorMessage(error.message);
});
}
};
return (
<View style={AppStyles.loginContainer}>
<KeyboardAvoidingView
style={AppStyles.backgroundCover}
behavior={Platform.OS === "ios" ? "padding" : null}
keyboardVerticalOffset={60}
>
<View style={AppStyles.loginScreen}>
<Text style={AppStyles.textHeader}>Login</Text>
<Text style={AppStyles.errorText}>{errorMessage}</Text>
<TextInput
style={AppStyles.input}
placeholder="Email"
placeholderTextColor="#fff"
value={email}
onChangeText={setEmail}
/>
<TextInput
style={AppStyles.input}
placeholder="Password"
placeholderTextColor="#fff"
secureTextEntry={true}
passwordRules={{ required: true, minLength: 6 }}
value={password}
onChangeText={setPassword}
/>
<View style={AppStyles.rowContainer}>
<Text style={AppStyles.text}>Don't have an account? </Text>
<TextButton
size="20px"
text="Sign Up"
color="#fff"
onPress={() => navigation.navigate("Signup")}
/>
</View>
<View style={AppStyles.rowContainer}>
<Text style={AppStyles.text}>Forgot your password? </Text>
<TextButton
size="20px"
text="Reset"
color="#fff"
onPress={() => navigation.navigate("ResetPassword")}
/>
</View>
<TextButton
size="20px"
text="Login"
backgroundColor="#83C9F4"
paddingVertical={6}
paddingHorizontal={12}
onPress={login}
/>
</View>
</KeyboardAvoidingView>
</View>
);
}
英文:
My react native code seems to execute appropriately. I still keep getting a bad setstate code error. Here is the error:
Warning: Cannot update a component (`ForwardRef(BaseNavigationContainer)`) while rendering a different component (`Login`). To locate the bad setState() call inside `Login`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
>> in Login (created by SceneView)
I was able to trace it back to this line (I think at least): Login @ Login.js:16
It would be this part of the code:
export function Login({navigation}){
if (auth.currentUser) {
navigation.navigate('Root')
} else {
onAuthStateChanged(auth, (user) => {
if (user) {
navigation.navigate("Root")
}
});
}
Here is the the entire component that appears to have the bad setState. I can't seem to figure out how to get this error to go away. All the code seems to be working ok, though...
export function Login({ navigation }) {
if (auth.currentUser) {
navigation.navigate("Root");
} else {
onAuthStateChanged(auth, (user) => {
if (user) {
navigation.navigate("Root");
}
});
}
let [errorMessage, setErrorMessage] = React.useState("");
let [email, setEmail] = React.useState("");
let [password, setPassword] = React.useState("");
let login = () => {
if (email !== "" && password !== "") {
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
navigation.navigate("Home", { user: userCredential.user });
// ...
})
.catch((error) => {
setErrorMessage(error.message);
});
}
};
return (
<View style={AppStyles.loginContainer}>
<KeyboardAvoidingView
style={AppStyles.backgroundCover}
behavior={Platform.OS === "ios" ? "padding" : null}
keyboardVerticalOffset={60}
>
<View style={AppStyles.loginScreen}>
<Text style={AppStyles.textHeader}>Login</Text>
<Text style={AppStyles.errorText}>{errorMessage}</Text>
<TextInput
style={AppStyles.input}
placeholder="Email"
placeholderTextColor={"#fff"}
value={email}
onChangeText={setEmail}
/>
<TextInput
style={AppStyles.input}
placeholder="Password"
placeholderTextColor={"#fff"}
secureTextEntry={true}
passwordRules={{ required: true, minLength: 6 }}
value={password}
onChangeText={setPassword}
/>
<View style={AppStyles.rowContainer}>
<Text style={AppStyles.text}>Don't have an account? </Text>
<TextButton
size={"20px"}
text={"Sign Up"}
color={"#fff"}
onPress={() => navigation.navigate("Signup")}
/>
</View>
<View style={AppStyles.rowContainer}>
<Text style={AppStyles.text}>Forgot your password? </Text>
<TextButton
size={"20px"}
text={"Reset"}
color={"#fff"}
onPress={() => navigation.navigate("ResetPassword")}
/>
</View>
<TextButton
size={"20px"}
text={"Login"}
backgroundColor="#83C9F4"
paddingVertical={6}
paddingHorizontal={12}
onPress={login}
/>
</View>
</KeyboardAvoidingView>
</View>
);
}
答案1
得分: 2
你应该始终在进行任何导航操作之前等待组件完全挂载。
你可以尝试将导航逻辑添加到 useEffect
中:
useEffect(() => {
if (auth.currentUser) {
navigation.navigate('Root')
}
const subscriber = onAuthStateChanged(auth, (user) => {
if (user) {
navigation.navigate("Root")
}
});
return subscriber
}, [])
英文:
You should always wait for your component to be fully mounted before any navigation action.
Can you try to add your navigation logic into a useEffect
?
useEffect(() => {
if (auth.currentUser) {
navigation.navigate('Root')
}
const subscriber = onAuthStateChanged(auth, (user) => {
if (user) {
navigation.navigate("Root")
}
});
return subscriber
}, [])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论