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

React如何将Authentication组件state传递至App.js及报错解决

问题修复方案

报错原因

TypeError: Cannot read properties of undefined (reading 'state') 报错源于两个核心错误:

  • App是函数组件,不存在this指向,你直接调用this.state时this为undefined,自然读取不到state属性
  • 父子组件传值逻辑颠倒:你需要把父组件的更新方法传递给子组件,由子组件在拿到用户数据后主动调用该方法更新父组件状态,而非在传递方法时就直接执行

修复步骤

1. 修改App.js代码

核心修改路由中Authentication组件的传参逻辑,直接把setUserData方法传递给子组件,不要提前执行:

import Home from './pages/Home';
import Book from './pages/Book'
import {Route, Switch} from 'react-router-dom'; 
import SavedBooks from './pages/SavedBooks';
import Header from './componens/Header';
import BookChapter from './pages/BookChapter';
import Authentication from './pages/Authentication';
import {useState} from "react";

function App(props) {
  // 初始值设为null更符合未登录状态
  const [userData,  setUserData] = useState(null);

  return (
    <div>
      <Header/>
      <Switch>
        <Route exact path="/" render={(props) => <Home {...props} userData={userData}/>}/>
        <Route exact path="/book/:id" component={Book}/>
        <Route exact path="/savedbooks" component={SavedBooks}/>
        <Route exact path="/book/:id/chapter/:numero" component={BookChapter}/>
        {/* 直接传递setUserData方法,不要提前执行 */}
        <Route exact path="/authentication" render={(props) => <Authentication {...props} setUserData={setUserData}/> }/>
      </Switch>
    </div>
  )
}
export default App;

2. 修改Authentication.js代码

首先接收父组件传递的setUserData方法,在登录/注册请求成功后调用该方法把用户数据同步到父组件,同时补全原代码缺失的事件处理函数:

import { useState } from "react"
import MyButton from "../componens/myButton"
import styles from "../style/authentication.module.css"
import Spinner from "../componens/Spinner"
import axios from "axios"

// 接收父组件传递的setUserData
const Authentication = ({setUserData}) =>{
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")
  const [loading, setLoading] = useState(false)
  const [registration, setRegistration] = useState(true)
  const [state, setState] = useState(null)

  let MyRegistration = null;

  // 补全缺失的邮箱输入处理函数
  const handleEmail = (e) => {
    setEmail(e.target.value)
  }
  // 补全缺失的密码输入处理函数
  const handlePassword = (e) => {
    setPassword(e.target.value)
  }
  // 补全缺失的登录注册切换函数
  const changeMode = () => {
    setRegistration(!registration)
  }

  const handleSubmit = async (e) =>{
    e.preventDefault()
    setLoading(true)
    try {
      const userKey = `AIzaSyCYe1XVuJVflRie0sf1y01RNrmQ77Dmp4Q`
      let urlAPI = `https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${userKey}`
      if (!registration) {
        urlAPI = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${userKey}`
      }
      MyRegistration = await axios.post(urlAPI,{
        email : email,
        password : password,
        returnSecureToken : true
      })
      setState(MyRegistration)
      // 调用父组件传递的方法,把用户数据同步到App.js的userData
      setUserData(MyRegistration)
      setLoading(false);
      return MyRegistration
    } catch (error) {
      setLoading(false)
      console.log(error)
    }
  }
  return <div className={styles.formContainer}>
    <h1>Authentication</h1>
    <form onSubmit={handleSubmit} action="">
        <p>Email</p>
        <input placeholder="Your email" type="email" value={email} onChange={handleEmail} />
        <p>Password</p>
        <input placeholder="Your Password" type="password" value={password} onChange={handlePassword} />
        {loading ? <Spinner/> :
        <MyButton  title={registration ? 'sign up' : 'Sign in'} handleClickButton={handleSubmit} />}
        <MyButton title={registration ? 'Go to Sign in' : 'Go to sign up'} handleClickButton={changeMode}/>
    </form>
  </div>
}
export default Authentication;

修改完成后即可实现用户登录状态从Authentication组件到App组件的同步,你可以直接使用App里的userData判断用户登录状态,开放对应功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:06:03