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

React组件未接收到react-router props问题求助

解决React登录组件中this.props为undefined且无法跳转的问题

我来帮你拆解下问题,然后给出几个实用的解决方案:

问题根源

  1. 函数组件不存在this:你写的Login和Index都是函数组件,函数组件里没有this对象,所以this.props必然是undefined,得直接用props参数来获取属性。
  2. 路由props未向下传递:Index组件是被Route直接渲染的,它能拿到路由相关的props(比如history),但你在Index里直接渲染Login/Home时,没把这些props传递给子组件,导致Login拿不到history。
  3. 回调函数的this指向问题:你在fetch的.then(function(data) { ... })里用了普通函数,这里的this指向不是组件实例,就算有this.props也会出错,换成箭头函数就能解决这个问题。

解决方案一:使用useHistory钩子(推荐,函数组件最佳实践)

React Router v5及以上版本提供了useHistory钩子,让函数组件可以直接获取history对象,完全不需要依赖props传递:

修改Login组件:

import React from 'react'
import { useHistory } from 'react-router-dom' // 导入useHistory钩子

const Login = () => {
  const history = useHistory(); // 获取history对象
  let user, pass

  const login = e => {
    e.preventDefault();
    fetch("http://localhost:3000/api/login", {
      method: "GET",
      headers: {
        "user": user.value,
        "pass": pass.value
      }
    })
    .then(response => response.json())
    .then(data => { // 换成箭头函数,避免this指向混乱
      if (data.user) {
        localStorage.setItem("username", data.user)
        history.push("/"); // 直接调用history.push完成跳转
      } else {
        console.log("Failed to get user")
      }
    })
  }

  return(
    <div>
      <h1>Login</h1>
      <form onSubmit={login}>
        <label>
          Username:
          <input type="text" className="form-control col-md-12" ref = {node => user = node}/>
        </label>
        <label>
          Password:
          <input type="password" className="form-control col-md-12" ref = {node => pass = node}/>
        </label>
        <br />
        <input type="submit" value="Submit" />
      </form>
    </div>
  )
}

export default Login

这个方案不需要修改Index组件,Login自己通过钩子就能拿到history,代码更简洁清晰。

解决方案二:手动传递路由props

如果你暂时不想用钩子,也可以通过手动传递props的方式解决:

  1. 修改Index组件,接收并传递路由props:
import React from 'react'
import Login from './Login'
import Home from './Home'

const Index = (props) => { // 接收Route传递的props
  if (localStorage.getItem("username")) {
    return <Home {...props} />; // 将所有props传递给Home组件
  } else {
    return <Login {...props} /> // 将所有props传递给Login组件
  }
}

export default Index
  1. 修改Login组件,接收props并使用:
import React from 'react'

const Login = (props) => { // 接收父组件传递的props
  let user, pass

  const login = e => {
    e.preventDefault();
    fetch("http://localhost:3000/api/login", {
      method: "GET",
      headers: {
        "user": user.value,
        "pass": pass.value
      }
    })
    .then(response => response.json())
    .then(data => { // 用箭头函数避免this指向问题
      if (data.user) {
        localStorage.setItem("username", data.user)
        props.history.push("/"); // 使用props中的history对象跳转
      } else {
        console.log("Failed to get user")
      }
    })
  }

  // 其余return部分保持不变
}

export default Login

额外提示

  • 实际项目中不建议用GET方法传递用户名和密码,这会把敏感信息暴露在URL里,建议改成POST方法,把参数放在请求体中。
  • 如果你的React Router是v6版本,useHistory已经被useNavigate替代,用法类似:const navigate = useNavigate();,跳转时用navigate("/")。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:23:54