我正在开发一个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不是一个函数。我究竟做错了什么?任何帮助都将受到欢迎。
在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);