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

React中useCallback与useEffect引发Hook调用顺序错误求助

问题原因

你遇到的错误是因为在字体加载完成前的早期返回语句,跳过了user状态和认证相关useEffect的初始化,违反了React Hook的核心规则:每次渲染时必须按相同顺序调用所有Hook。当字体未加载时,组件提前返回,导致后续Hook不执行;而字体加载完成后,这些Hook又会被调用,两次渲染的Hook顺序不一致,从而触发错误。

修复方案

将所有Hook调用移到组件顶部、早期返回语句之前,确保每次渲染都按相同顺序执行所有Hook,同时保留原有功能。

修正后的代码

// App.js

// 所有导入均正确

SplashScreen.preventAutoHideAsync();

export default function App() {
  // 加载字体
  const [fontsLoaded, fontError] = useFonts({
    "SF-Pro-Display-Regular": require("./assets/fonts/SF-Pro-Display-Regular.otf")
  });

  // 用户检测 - 移至所有Hook调用序列中
  const [user, setUser] = useState(null);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (authUser) => {
      setUser(authUser);
    });

    return unsubscribe; // 返回取消订阅的函数
  }, []);

  const onLayoutRootView = useCallback(async () => {
    if (!fontError && fontsLoaded) {
      await SplashScreen.hideAsync();
    }
  }, [fontError, fontsLoaded]);

  // 早期返回放在所有Hook之后
  if (!fontsLoaded && !fontError) {
    return null;
  }

  return (
    <View style={{ flex: 1 }} onLayout={onLayoutRootView}>
      <NavigationContainer>
        {user !== null ? <AppNavigation /> : <InitialNavigation />}
      </NavigationContainer>
    </View>
  );
}
说明
  • 所有Hook(useFonts、useState、useEffect、useCallback)现在都在组件最顶部按固定顺序执行,确保每次渲染的Hook调用顺序一致。
  • 字体加载、启动页隐藏、用户认证检测的逻辑完全保留,功能不受影响。
  • 即使字体还在加载,用户认证检测仍会正常执行,避免了不必要的等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:40:34