You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中Invalid Hook Call问题:模块化用户数据读取后报错

问题分析与解决方案

核心错误原因

  • Hook使用违规:getLoggedInUser是普通异步函数,却在内部调用了useState Hook。React规定Hook只能在React组件函数的顶层或者**自定义Hook(以use开头的函数)**中调用,普通函数里用Hook必然触发invalid hook call错误。
  • 异步处理错误:getLoggedInUser是async函数,直接赋值let userData = getLoggedInUser(text)得到的是Promise对象,不是实际用户数据,后续的判空逻辑完全失效。
  • 导航逻辑未执行:login函数里的() => navigation.navigate('Home', {user: userData})是个未执行的匿名函数,不会触发页面跳转。

修正方案

1. 重构数据读取函数,移除Hook

把getLoggedInUser改成纯异步工具函数,不需要用useState,直接返回查询到的用户数据:

// 数据读取文件
export default async function getLoggedInUser(name) {
  try {
    const querySnapshot = await firestore().collection('users').get();
    let foundUser = null;
    querySnapshot.forEach(doc => {
      if (doc.data().name === name) {
        foundUser = doc;
      }
    });
    return foundUser;
  } catch (error) {
    console.error(error);
    return null;
  }
}

这里用await替代.then简化异步逻辑,直接用变量存储查询结果,无需状态管理。

2. 修正login函数的异步处理与导航逻辑

因为getLoggedInUser是异步函数,需要用await获取结果,同时修正判空和导航逻辑:

const login = async (text, navigation) => {
  const userData = await getLoggedInUser(text);
  // 修正判空逻辑:用&&避免永远为true的无效判断
  if (userData !== null && userData !== undefined) {
    navigation.navigate('Home', {user: userData});
  } else {
    console.log('未找到对应用户');
  }
}

3. 确保组件内调用逻辑正确

Login组件里的Pressable onPress直接调用async的login函数即可:

// Login组件内的Pressable
<Pressable
  style={[styles.button, styles.buttonClose]}
  onPress={() => login(name, navigation)}
>
  {/* 按钮内容 */}
</Pressable>

额外优化建议

如果后续需要在组件中管理用户状态,可以创建自定义Hook(必须以use开头),在Hook内部处理异步查询和状态:

// 自定义Hook示例
export function useLoggedInUser(name) {
  const [userData, setUserData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchUser = async () => {
      try {
        const user = await getLoggedInUser(name);
        setUserData(user);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    };
    if (name) fetchUser();
  }, [name]);

  return { userData, loading, error };
}

在Login组件中使用:

function Login({ navigation }) {
  const [name, onChangeNameText] = React.useState('');
  // 实时查询用户(可选)
  // const { userData, loading } = useLoggedInUser(name);

  return (/* ... */);
}

内容的提问来源于stack exchange,提问作者Wei Xiong

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:00:31