【问题标题】:Expo React Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your applicationExpo React 警告:无法对未安装的组件执行 React 状态更新。这是一个无操作,但它表明您的应用程序中存在内存泄漏
【发布时间】:2021-11-14 17:16:10
【问题描述】:

我是本机反应的新手,并且正在关注有关如何与 firebase auth 连接的媒体教程。一切似乎都正常,但我不断收到以下警告:

警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

我几乎完全按照教程中所说的做了,并尝试了其他一些方法来修复它,但似乎没有任何效果。这是它指向错误的代码:

    let currentUserUID = firebase.auth().currentUser.uid;

    const [firstName, setFirstName] = useState('');

    useEffect(() => { 
        getUserInfo();
      })

      async function getUserInfo(){
        try {
          let doc = await firebase
            .firestore()
            .collection('users')
            .doc(currentUserUID)
            .get();
  
          if (!doc.exists){
            Alert.alert('No user data found!')
          } else {
            let dataObj = doc.data();
            setFirstName(dataObj.firstName)
          }
        } catch (err){
        Alert.alert('There is an error.', err.message)
        }
      }

如果有人能帮我解决这个问题并解释到底出了什么问题,那就太好了。

这是我正在学习的教程的link

【问题讨论】:

    标签: reactjs firebase react-native expo use-effect


    【解决方案1】:

    您的getInfoUser() 函数是async。你应该在useEffect 中做这样的事情:

    useEffect(async () => { await getUserInfo(); }, [])
    

    useEffect 中的第二个参数使用依赖数组。使用依赖数组等同于componentDidMount

    您的效果只会在组件首次渲染时发生一次。此外,在某些情况下,您需要在 useEffect 中提供清理功能,如下所示:

    return () => { 
       //do something or cancel a subscription
    }
    

    【讨论】:

    • useEffect 钩子回调不能是async,这就是为什么 getUserInfo 被单独声明并在 in 钩子回调中调用的原因。这不是一个很好的答案,因为您基本上说过要做 React 警告已经声明要做的事情。
    【解决方案2】:

    这里的问题是您可能会在组件卸载后将状态更新加入队列。由于您是直接异步访问您的 firestore,因此您可以使用 React ref 来跟踪组件是否在 排队更新之前仍然挂载。

    const isMountedRef = React.ref(null);
    
    useEffect(() => {
      isMountedRef.current = true;               // set true when mounted
      return () => isMountedRef.current = false; // clear when unmounted
    }, []);
    
    useEffect(() => {
      async function getUserInfo(){
        try {
          let doc = await firebase
            .firestore()
            .collection('users')
            .doc(currentUserUID)
            .get();
    
          if (!doc.exists){
            Alert.alert('No user data found!')
          } else {
            let dataObj = doc.data();
            if (isMountedRef.current) { // <-- check if still mounted
              setFirstName(dataObj.firstName);
            }
          }
        } catch (err){
          Alert.alert('There is an error.', err.message)
        }
      }
      getUserInfo();
    }, []); // <-- include dependency array, empty to run once when mounting
    

    【讨论】:

      猜你喜欢
      • 2021-08-09
      • 2020-06-27
      • 2019-12-31
      • 2020-01-24
      • 2021-06-29
      • 2020-09-18
      • 2021-11-25
      • 2021-12-09
      • 2021-05-14
      相关资源
      最近更新 更多