【问题标题】:TypeError: Cannot read property 'props' of undefined In a React functionTypeError:无法在 React 函数中读取未定义的属性“道具”
【发布时间】:2019-09-27 13:27:17
【问题描述】:

我有一个正在对用户进行身份验证的 userContext。它正在工作,但在成功登录后,我希望将用户定向到 /dashboard。所以我正在使用 this.props.history.push('/dashboard'); 但我收到以下错误。

TypeError: 无法读取未定义的属性“props”

有没有更好的方法来做到这一点?在使用函数时?

UserContext.js

import React, {useState, createContext, useEffect} from 'react'
import Firebase from 'firebase'
import { Redirect } from 'react-router'

export const UserContext = createContext();


export const UserProvider = props => {
  const [user, setUser] = useState({
    username: "blank",
    loggendIn: false
  });


  var id = localStorage.getItem('id');
  // check if its null
  console.log(id);
  useEffect(() => {
    if (id != null) {
      console.log('id is there');
      // load user from realtime database
      const dbOBJ = Firebase.database().ref().child("users").child(id);
      dbOBJ.on('value', function(snapshot) {
        setUser(snapshot.val());
      });

    } else {
      console.log('no id :( ');
    }
    console.log(props.history);
    this.props.history.push('/dashboard');
  }, [id]);

  return (
    <UserContext.Provider value = {[user, setUser]} >
    {  props.children}
    </UserContext.Provider>
  );
}

app.js

import React from 'react';
import NavBar from './components/navBar';
import Login from './components/login';
import Session from './components/session';
import Dashboard from './components/dashboard';
import './App.css';
import Container from '@material-ui/core/Container';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';

import { UserProvider } from './model/UserContext'


function App() {

  return (
    <div>
      <UserProvider>
      <Session />
       <NavBar />
        <Container maxWidth="sm">
         <Router>
         <Route path='/Login' component={Login}  />
         <Route path='/Dashboard' component={Dashboard}  />
         </Router>
       </Container>
      </UserProvider>
    </div>
  );
}

export default App;

【问题讨论】:

  • history 属性从何而来?它通常通过来自 react-router 的withRouter HOC 注入。
  • 你会这样使用'withRouter'吗? export const UserProvider = props => withRouter({
  • no...更像const UserProvider = withRouter((props =&gt; {...});,但老实说,正常编写函数组件更容易,然后包装导出,如export default withRouter(UserProvider);
  • 这认为这是这样做的方法,但我得到一个错误尝试导入错误:'UserProvider' 不是从'./model/UserContext' 导出的。我正在导出函数const UserProvider = props =&gt; { ... }export default withRouter(UserProvider);

标签: javascript reactjs react-router


【解决方案1】:

这是一个功能组件,没有this 存在的实例,历史只会在props 上。您可能还需要将路由器的历史对象“注入”到道具中。

import React, {useState, createContext, useEffect} from 'react'
import Firebase from 'firebase'
import { Redirect, withRouter } from 'react-router'

export const UserContext = createContext();


const UserProvider = ({  // don't export here
  children, // destructuring props here so it is clearer
  history
}) => {
  const [user, setUser] = useState({
    username: "blank",
    loggendIn: false
  });


  var id = localStorage.getItem('id');
  // check if its null
  console.log(id);
  useEffect(() => {
    if (id != null) {
      console.log('id is there');
      // load user from realtime database
      const dbOBJ = Firebase.database().ref().child("users").child(id);
      dbOBJ.on('value', function(snapshot) {
        setUser(snapshot.val());
      });
    } else {
      console.log('no id :( ');
    }
    console.log(props.history);
    history.push('/dashboard'); // <-- no this.props, just props or destructured props
  }, [id]);

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

export default withRouter(UserProvider);

【讨论】:

  • 感谢您这么快回复我,我这样做时的问题是。它说“TypeError:无法读取未定义的属性'push'”。我需要在 app.js 中推送道具吗?我会将代码添加到帖子中。
  • 更新显示使用路由器的withRouter HOC。
  • 我认为这是这样做的方法,但我收到错误尝试导入错误:'UserProvider' 不是从'./model/UserContext' 导出的。但我正在导出函数 const UserProvider = props => { ... } export default withRouter(UserProvider);我需要在 app.js 中添加一些东西吗?
  • 啊,我明白了,尝试从导出中删除 default 部分,或者尝试在导入中删除 {}。问题是,如果您执行默认导出,那么导入将简单地为 import UserProvider from './model/UserContext';,或者如果您想将其保留为命名导出,则必须执行 export const UserProvider = withRouter(props =&gt; ...
  • 是的,修复了它 :) 但又出现了一个错误,哈哈,```错误:“不变式失败:您不应该在 之外使用 ”``我将 移到 app.js 文件中 App 函数的 return() 列表顶部。但仍然遇到同样的问题。
【解决方案2】:

我认为你混淆了多个东西:

胖箭头函数上没有 this 定义它会选择 window 作为您的代码。

window.name = 'Mamba';
(() => {console.log(this.name)})();

所以你需要像这样直接在这里使用道具:

this.props.history.push('/dashboard'); => props.history.push('/dashboard');

如果你仍然不成功,你可能想通过this question

【讨论】:

  • 我认为你是对的,但我让“history.push”我们失踪了。我需要将它添加到 app.js 中吗? props.history.push() 是内置在 react 中的吗?还是我应该使用其他东西来重定向?
猜你喜欢
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
  • 2023-04-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多