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

在React Navigation中向Stack.Screen传递useState函数失败

解决React Navigation传递setIsAuthenticated函数到SignIn页面的问题

你的核心问题是错误地将setIsAuthenticated传给了Screen的options属性,options是用来配置导航栏样式、跳转行为等导航选项的,并非传递组件props的正确方式。以下是几种修复方案:

方案一:使用initialParams传递参数

修改AuthRoutes中SignIn对应的Screen配置,把setIsAuthenticated放到initialParams里:

<Navigator screenOptions={{ headerShown: false }} initialRouteName="Welcome">
  <Screen key="Welcome" name="Welcome" component={Welcome} />
  {/* 这里修改为initialParams传递 */}
  <Screen 
    key="SignIn" 
    name="SignIn" 
    component={SignIn} 
    initialParams={{ setIsAuthenticated: setIsAuthenticated }}
  />
  <Screen key="SignUp" name="SignUp" component={Register} />
  <Screen key="ForgotPassword" name="ForgotPassword" component={ForgotPassword} />
</Navigator>

然后在SignIn页面中,通过route.params获取该函数:

export function SignIn({ navigation, route }: any) {
  const { setIsAuthenticated } = route.params;
  // 后续可直接调用setIsAuthenticated(true)完成登录状态更新
  
  const [forgotEmail, setForgotEmail] = useState('');
  const [showModal, setShowModal] = useState(false);

  // ...其余代码不变
}

方案二:直接包装组件传递props

在AuthRoutes中,对SignIn组件进行包装,直接将setIsAuthenticated作为props传入:

<Screen 
  key="SignIn" 
  name="SignIn" 
  component={(navProps) => <SignIn {...navProps} setIsAuthenticated={setIsAuthenticated} />}
/>

这种方式下,SignIn页面可以直接从props中拿到setIsAuthenticated,你原来的console.log(props)就能看到该函数了。

方案三:用React Context全局管理(推荐)

如果认证状态需要在多个页面共享,层层传递props会导致代码冗余,推荐用Context统一管理:

1. 创建AuthContext

// contexts/AuthContext.tsx
import React, { createContext, useContext, useState, useEffect } from 'react';
import auth from '../你的auth路径'; // 替换为你的auth实例路径

type AuthContextType = {
  isAuthenticated: boolean;
  setIsAuthenticated: (value: boolean) => void;
};

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    auth.onAuthStateChanged((user) => {
      if (user?.emailVerified) {
        setIsAuthenticated(true);
      }
    });
  }, []);

  return (
    <AuthContext.Provider value={{ isAuthenticated, setIsAuthenticated }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth必须在AuthProvider内部使用');
  }
  return context;
}

2. 在App.tsx中包裹AuthProvider

import { AuthProvider, useAuth } from './contexts/AuthContext';

export default function App() {
  useEffect(() => {
    setLocale('pt');
  }, []);

  if (!fontsLoaded) return <>></>;

  return (
    <ThemeProvider theme={theme}>
      <AuthProvider>
        {/* 直接通过useAuth获取认证状态 */}
        {!useAuth().isAuthenticated ? (
          <NavigationContainer>
            <AuthRoutes />
          </NavigationContainer>
        ) : (
          <Provider store={store}>
            <Main />
          </Provider>
        )}
      </AuthProvider>
      <ToastMessage />
    </ThemeProvider>
  );
}

3. 在SignIn页面直接使用useAuth

import { useAuth } from '../../contexts/AuthContext';

export function SignIn({ navigation }: any) {
  const { setIsAuthenticated } = useAuth();
  // 登录成功后直接调用setIsAuthenticated(true)即可

  const [forgotEmail, setForgotEmail] = useState('');
  const [showModal, setShowModal] = useState(false);

  // ...其余代码不变
}

这种方式无需手动传递props,任何页面都能通过useAuth()获取认证状态和更新函数,代码更简洁易维护。

内容的提问来源于stack exchange,提问作者Nilton Schumacher F

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 03:48:24