【问题标题】:Cannot read property 'push' of undefined onClick无法读取未定义 onClick 的属性“推送”
【发布时间】:2020-01-30 21:50:01
【问题描述】:

我正在使用 aws cognito 创建登录系统。在 Navbar.js 组件中,我有一个 Log Out 按钮,我想在单击它后重定向它。我使用 push 方法进行重定向,但收到错误“无法读取未定义的属性 'push'”。

此方法适用于除此之外的所有其他组件。所有组件的所有导入都相同。

这是因为 Navbar.js 组件没有嵌套在 App.js 中的 Switch 组件内吗?这是我能想到的唯一可能导致问题的事情......

Navbar.js

import React, { Component } from "react";
import { Auth } from "aws-amplify";

export default class Navbar extends Component {
  handleLogOut = async event => {
    event.preventDefault();
    try {
      Auth.signOut();
      this.props.auth.setAuthStatus(false);
      this.props.auth.setUser(null);
      this.props.history.push("/");
    } catch (error) {
      console.log(error.message);
    }
  };

  render() {
    return (
      <nav className="navbar" role="navigation" aria-label="main navigation">
        <div className="navbar-brand">
          <a className="navbar-item" href="/">
            <img
              src="hexal-logo.png"
              width="112"
              height="28"
              alt="hexal logo"
            />
          </a>
        </div>

        <div id="navbarBasicExample" className="navbar-menu">
          <div className="navbar-start">
            <a href="/" className="navbar-item">
              Home
            </a>
            <a href="/products" className="navbar-item">
              Products
            </a>
            <a href="/admin" className="navbar-item">
              Admin
            </a>
          </div>

          <div className="navbar-end">
            <div className="navbar-item">
              {this.props.auth.isAuthenticated && this.props.auth.user && (
                <p>Hello {this.props.auth.user.username}</p>
              )}
              <div className="buttons">
                {!this.props.auth.isAuthenticated && (
                  <>
                    <a href="/register" className="button is-primary">
                      <strong>Register</strong>
                    </a>
                    <a href="/login" className="button is-light">
                      Log in
                    </a>
                  </>
                )}
                {this.props.auth.isAuthenticated && (
                  <a
                    href="/"
                    onClick={this.handleLogOut}
                    className="button is-light"
                  >
                    Log Out
                  </a>
                )}
              </div>
            </div>
          </div>
        </div>
      </nav>
    );
  }
}

App.js

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import "./App.css";
import Navbar from "./components/Navbar";
import Home from "./components/Home";
import Products from "./components/Products";
import ProductAdmin from "./components/ProductAdmin";
import LogIn from "./components/auth/LogIn";
import Register from "./components/auth/Register";
import ForgotPassword from "./components/auth/ForgotPassword";
import ForgotPasswordVerification from "./components/auth/ForgotPasswordVerification";
import ChangePassword from "./components/auth/ChangePassword";
import ChangePasswordConfirm from "./components/auth/ChangePasswordConfirm";
import Welcome from "./components/auth/Welcome";
import Footer from "./components/Footer";
import { Auth } from "aws-amplify";
import { library } from "@fortawesome/fontawesome-svg-core";
import { faEdit } from "@fortawesome/free-solid-svg-icons";
library.add(faEdit);

class App extends Component {
  state = {
    isAuthenticated: false,
    isAuthenticating: true,
    user: null
  };

  setAuthStatus = authenticated => {
    this.setState({ isAuthenticated: authenticated });
  };

  setUser = user => {
    this.setState({ user: user });
  };

  async componentDidMount() {
    try {
      const session = await Auth.currentSession();
      this.setAuthStatus(true);
      console.log(session);
      const user = await Auth.currentAuthenticatedUser();
      this.setUser(user);
    } catch (error) {
      console.log(error);
    }
    this.setState({ isAuthenticating: false });
  }

  render() {
    const authProps = {
      isAuthenticated: this.state.isAuthenticated,
      user: this.state.user,
      setAuthStatus: this.setAuthStatus,
      setUser: this.setUser
    };
    return (
      !this.state.isAuthenticating && (
        <div className="App">
          <Router>
            <div>
              <Navbar auth={authProps} />
              <Switch>
                <Route
                  exact
                  path="/"
                  render={props => <Home {...props} auth={authProps} />}
                />
                <Route
                  exact
                  path="/products"
                  render={props => <Products {...props} auth={authProps} />}
                />
                <Route
                  exact
                  path="/admin"
                  render={props => <ProductAdmin {...props} auth={authProps} />}
                />
                <Route
                  exact
                  path="/login"
                  render={props => <LogIn {...props} auth={authProps} />}
                />
                <Route
                  exact
                  path="/register"
                  render={props => <Register {...props} auth={authProps} />}
                />
                <Route
                  exact
                  path="/forgotpassword"
                  render={props => (
                    <ForgotPassword {...props} auth={authProps} />
                  )}
                />
                <Route
                  exact
                  path="/forgotpasswordverification"
                  render={props => (
                    <ForgotPasswordVerification {...props} auth={authProps} />
                  )}
                />
                <Route
                  exact
                  path="/changepassword"
                  render={props => (
                    <ChangePassword {...props} auth={authProps} />
                  )}
                />
                <Route
                  exact
                  path="/changepasswordconfirmation"
                  render={props => (
                    <ChangePasswordConfirm {...props} auth={authProps} />
                  )}
                />
                <Route
                  exact
                  path="/welcome"
                  render={props => <Welcome {...props} auth={authProps} />}
                />
              </Switch>
              <Footer />
            </div>
          </Router>
        </div>
      )
    );
  }
}

export default App;

【问题讨论】:

  • 问题是您的Navbar 组件不是&lt;Route/&gt; 组件或类似的东西,它只是呈现为&lt;Router/&gt; 的子组件 - 这并没有赋予它固有的访问权限反应路由器的history 道具。您必须使用 Emanuele 的答案手动将 history 属性传递给它。

标签: reactjs amazon-web-services react-router


【解决方案1】:

您忘记使用withRouter HOC 将组件附加到路由器:

import { withRouter } from "react-router-dom";

class Navbar extends Component {
  ...
}

export default withRouter(Navbar)

【讨论】:

    【解决方案2】:

    我不是 React 专家,但看起来您正在尝试调用 this.props.history.push("/");,而在您调用组件时未定义 history,此处仅定义了 auth

    <Navbar auth={authProps} />
    

    【讨论】:

      【解决方案3】:

      您可以像@emanuele 提到的那样使用 withRouter 钩子,或者将历史道具从 app.js 传递给组件

      【讨论】:

        猜你喜欢
        • 2021-03-06
        • 1970-01-01
        • 1970-01-01
        • 2017-08-12
        • 1970-01-01
        • 2016-04-22
        相关资源
        最近更新 更多