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

React Native中setUser未定义报错:Firebase认证正常但状态更新失败

React Native + Firebase 登录/注册:setUser is not a function 错误修复

问题概述

在React Native项目中使用Firebase实现登录/注册功能时,出现以下问题:

  • Firebase能成功接收用户信息,控制台日志正常输出,但抛出TypeError: setUser Is Not A Function, (It Is Undefined)错误
  • 将useAuth的对象解构改为数组解构后,页面直接无法加载

相关代码

Register.js

import { StyleSheet, Text, View, Button, TextInput, Alert } from 'react-native';
import { useState } from 'react';
import { getAuth, createUserWithEmailAndPassword } from 'firebase/auth';
import React from 'react';

import LoginPage from './LoginPage';
import { authentication } from './Config';
import { useAuth } from './AuthContext';

export default function RegisterPage({navigation}) {

  const [email, setEmail]  = useState("");
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const {user, setUser}= useAuth();

  const signUp = () => {
    createUserWithEmailAndPassword(authentication, email, password)
      .then((res) => {
        console.log('You Have Successfully Created An Account!');
        setUser(res.user);
      })
      .catch((re) => {
        console.log(re);
      })

   }


  return (
    <View style={styles.container}>
      <Text>Welcome! Create Your Account Here</Text>
      <TextInput style = {styles.input}
       keyboardType='email-address'
       placeholder='Please Enter Your E-Mail Here'
       placeholderTextColor={'#aa336a'}
       value={email}
       onChangeText={(text) => setEmail(text)}
    />
     <TextInput
     style = {styles.input}
     placeholder='Please Enter Your Password Here'
     placeholderTextColor={'#aa336a'}
     secureTextEntry
     value={password}
     onChangeText={(text) => setPassword(text)}
  />
  <TextInput
     style = {styles.input}
     placeholder='Please Confirm Your Password Here'
     placeholderTextColor={'#aa336a'}
     secureTextEntry
     value={confirmPassword}
     onChangeText={(text) => setConfirmPassword(text)}
  />
  <Button title='Create An Account'  onPress={signUp}></Button>
  <Button title='Not Your First Time Here?' onPress={() => navigation.push('Login')}></Button>
</View>
);
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   backgroundColor: '#ffb3c6',
   alignItems: 'center',
   justifyContent: 'center',
 },
 input: {
 width: 340,
 height: 57,
 backgroundColor: '#d6b4fc',
 alignItems:'center',
 justifyContent: 'center',
 marginTop: 17
},
});

Login.js

import { StyleSheet, Text, View, Button, Alert, TextInput } from 'react-native';
import { useRef, useState } from 'react'
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
import React from 'react';
import RegisterPage from './RegisterPage';
import { authentication } from './Config';
import { useAuth } from './AuthContext';

export default function LoginPage({navigation}) {

  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const {user,  setUser } = useAuth();

  const inputRef = useRef();
  const passwordRef = useRef();



  const signIn = async () => {

    signInWithEmailAndPassword(authentication, email, password)
      .then ((res) =>{
        console.log('You Have Successfully Signed In!');
        setUser(res.user);
      })

      .catch ((err) => {
        console.log(err);
        setError('Error In Signing In')
      })

  };

  return (
    <View style={styles.container}>
      <Text>Welcome Back! Please Sign In</Text>
     <TextInput
         ref={inputRef}
         style={styles.input}
         placeholder='Please Enter Your E-Mail Here'
         keyboardType='email-address'
         placeholderTextColor={'#aa336a'}
         value={email}
         onChangeText={(email) => setEmail(email)}
      />
       <TextInput
         ref={passwordRef}
         style= {styles.input}
         placeholder='Please Enter Your Password Here'
         placeholderTextColor={'#aa336a'}
         value={password}
         secureTextEntry
         onChangeText={(text) => setPassword(text)}
      />
      <Button title='Login' onPress={signIn}></Button>
      <Button title='First Time Here?'onPress={() => navigation.push('Register')}></Button>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  input: {
    width: 340,
    height: 57,
    backgroundColor: '#d6b4fc',
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 17
  },
});

AuthContext.js

import React from "react";
import { useState } from "react";
import { useContext } from "react";

const AuthContext = React.createContext();

export const AuthProvider =({children}) => {
    const [user, setUser] = useState(null);

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

export const useAuth = () => useContext(AuthContext);
export default AuthContext;

问题根源

核心原因是使用useAuth的组件没有被AuthProvider包裹:

  • AuthContext通过React.createContext()创建且未传入默认值,当组件不在AuthProvider范围内时,useContext(AuthContext)返回undefined
  • 解构{user, setUser}时,从undefined中取属性会导致setUser为undefined,触发函数调用错误
  • 改成数组解构时,尝试从undefined中取数组元素,直接引发页面崩溃
  • Firebase操作正常是因为登录/注册逻辑直接调用了Firebase SDK,与AuthContext的状态管理无关

解决方案

1. 用AuthProvider包裹根组件

找到App入口文件(如App.js),将导航容器或所有需要访问AuthContext的组件用AuthProvider包裹:

import { AuthProvider } from './AuthContext';
import { NavigationContainer } from '@react-navigation/native';
import AuthStack from './AuthStack'; // 你的登录/注册导航栈

export default function App() {
  return (
    <AuthProvider>
      <NavigationContainer>
        <AuthStack />
      </NavigationContainer>
    </AuthProvider>
  );
}

2. 保持对象解构方式

useAuth返回的是对象,继续使用const {user, setUser} = useAuth();,不要改成数组解构。

3. 修复Login.js中的未定义变量

Login.js中使用了setError但未声明对应的state,补充如下:

// 在LoginPage组件内添加
const [error, setError] = useState("");

4. 可选优化:注册密码校验

在注册时增加两次密码一致性校验,提升用户体验:

const signUp = () => {
  if (password !== confirmPassword) {
    Alert.alert("错误", "两次输入的密码不一致");
    return;
  }
  // 原Firebase注册逻辑
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:07:04