英文:
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
}, [])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论