首页 > 解决方案 > React Native Firestore 无限循环

问题描述

我正在尝试使用 documentSnapshot 从 firestore 获取用户数据,我可以获取数据,但它陷入了无限循环,更新了用户数据,

这是代码

import firestore from '@react-native-firebase/firestore';
export default function HomeScreen() {
     const { user, logout } = useContext(AuthContext);
     const [currentUser, setCurrentUser] = useState('');

     useEffect(() => {
      firestore()
           .collection('users')
           .doc(user.uid)
           .get()
           .then(documentSnapshot => {
                if (documentSnapshot.exists) {
                     setCurrentUser(documentSnapshot.data())
                }
           })

 })
 return (
      <View style={styles.container}>
           <Title>{currentUser.displayName}</Title>
           <FormButton
                modeValue='contained'
                title='Logout'
                onPress={() => logout()} />
      </View>
 )
}

标签: javascriptreactjsfirebasereact-nativereact-native-firebase

解决方案


每次您调用时,setCurrentUser您都会强制重新渲染(因为这是一个状态变量)。你的useEffectthen 再次触发,它再次调用setCurrentUser,依此类推,导致无限循环。

useEffect为了防止这种情况,您应该设置一个在触发之前应该监听的变量列表。您可以通过将第二个参数传递给useEffect.

useEffect(() => {
  // your function call
}, [/* list of state/prop variables to respond to */])

如果您只想useEffect触发一次,类似于componentDidMount,您可以传递一个空数组。

文档

如果你想运行一个效果并且只清理一次(在挂载和卸载时),你可以传递一个空数组([])作为第二个参数。这告诉 React 你的效果不依赖于任何来自 props 或 state 的值,所以它永远不需要重新运行。这不是作为特殊情况处理的——它直接遵循依赖项数组的工作方式。

在您的情况下,您似乎可能希望放置user在此数组中,因为这是您的 firestore 调用所依赖的唯一变量。如果user.uid没有改变,则没有理由再次触发此效果。


推荐阅读