React&React Router,无法调用父函数

问题描述 投票:-1回答:1

我正在开发一个React应用(具有react-router-dom,并尝试调用父组件App中定义的函数。父组件的定义如下:

import React, { Component, Fragment } from 'react';
import { Link, NavLink } from 'react-router-dom';
import Routes from './components/routes';
import { withRouter } from 'react-router';
import { Auth } from "aws-amplify";
import Login from './components/Login';
import logo from './logo.svg';
import './App.css';


class App extends Component {
  constructor(props) {
    super(props);
    this.userHasAuthenticated = this.userHasAuthenticated.bind(this);
    this.state = {
      isAuthenticated: false
    }
  }

  userHasAuthenticated = (value) => {
    this.setState({ isAuthenticated: value });
  }

  handleLogout = async event => {
    await Auth.signOut();
    this.userHasAuthenticated(false);
    this.props.history.push("/");
  }

  async componentDidMount() {
    try {
      await Auth.currentSession();
      this.userHasAuthenticated(true);
      this.props.history.push("/chat");
    } catch(e) {
      if (e !== 'No current user') {
        alert(e);
      }
    }
  }

  render() {
    return (
      <Fragment>
        <div className="navbar navbar-expand-lg navbar-light bg-light">
            <Link to="/" className="navbar-brand" href="#"><h1>Sample App</h1></Link>
              <div className="collapse navbar-collapse" id="navbarNav">
                  <ul className="navbar-nav">
                    {this.state.isAuthenticated ? 
                      <Fragment>
                        <li className="nav-item">
                          <NavLink to="/chat" className="nav-link">Chat</NavLink>
                        </li>
                        <li className="nav-item">
                          <NavLink to="/" className="nav-link" onClick={this.handleLogout}>Logout</NavLink>
                        </li>
                      </Fragment> : 
                      <Fragment>
                        <li className="nav-item">
                          <NavLink to="/" className="nav-link">Login</NavLink>
                        </li>
                        <li className="nav-item">
                          <NavLink to="/Signup" className="nav-link">Signup</NavLink>
                        </li>
                      </Fragment>
                    } 
                  </ul>
              </div>
        </div>
        <Routes userHasAuthenticated= { this.userHasAuthenticated } isAuthenticated = { this.state.isAuthenticated }/>
      </Fragment>
    );
  }
}

export default withRouter(App);

登录组件应该对用户进行身份验证,更新状态(使用父组件中定义的hasUserAuthenticated函数,并将用户重定向到另一个页面。

import React, { Component } from "react";
import { FormGroup, FormControl, FormLabel, Button } from "react-bootstrap";
import { Auth } from "aws-amplify";

export default class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: "",
            password: ""
        };
    }

    validateForm() {
        return this.state.email.length > 0 && this.state.password.length>0;
    }

    handleChange = event => {
        this.setState({
                [event.target.id]: event.target.value
            });
    }

    handleSubmit = async event => {
        event.preventDefault();
        try {
            await Auth.signIn(this.state.email, this.state.password);
            this.userHasAuthenticated(true);
            this.props.history.push("/chat");
        } catch (e) {
            alert(e.message);
        }
    }

    render() {
        return (
            <div className="Home">
                <div className="col-md-4"> 
                    <form onSubmit={this.handleSubmit}>
                        <FormGroup controlId="email">
                            <FormLabel>Email</FormLabel>
                            <FormControl
                                autoFocus
                                type="email"
                                value={this.state.email}
                                onChange={this.handleChange}
                            />
                        </FormGroup>
                        <FormGroup controlId="password" >
                            <FormLabel>Password</FormLabel>
                            <FormControl
                                value={this.state.password}
                                onChange={this.handleChange}
                                type="password"
                            />
                        </FormGroup>
                        <Button type="submit">
                        Login
                        </Button>
                    </form>
                </div>
            </div>
        );
    }
}

“我的路线”组件如下所示:

import React from 'react';
import Signup from './Signup';
import Login from './Login';
import NotFound from './NotFound';
import chat from './chat';

import { Route, Switch } from "react-router-dom";

export default ( { childProps } ) =>
<Switch>
    <Route exact path ="/" component={Login} props={childProps}/>
    <Route exact path ="/Signup" component={Signup} props={childProps}/>
    <Route exact path ="/chat" component={chat} props={childProps}/>
    <Route component={NotFound} />
</Switch>;

但是,应用程序抛出错误,说this.userHasAuthenticated不是一个函数。我究竟做错了什么?任何帮助都将受到欢迎。

javascript reactjs react-router
1个回答
1
投票

Routes.js中,您需要进行这些更改

import React from 'react';
import Signup from './Signup';
import Login from './Login';
import NotFound from './NotFound';
import Chat from './chat';

import { Route, Switch } from "react-router-dom";

export default parentProps =>
<Switch>
    <Route exact path ="/" render={(props => <Login {...props} {...parentProps} />) />
    <Route exact path ="/Signup" render={(props => <Signup {...props} {...parentProps} />) />
    <Route exact path ="/chat" render={(props => <Chat {...props} {...parentProps} />) />
    <Route component={NotFound} />
</Switch>;

并且在Login或任何子组件中也请使用this.props.userHasAuthenticated(true);而不是this.userHasAuthenticated(true);

© www.soinside.com 2019 - 2024. All rights reserved.