【发布时间】:2020-01-27 16:51:18
【问题描述】:
我正在开发一个 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 不是函数。我究竟做错了什么?欢迎任何帮助。
【问题讨论】:
-
是的,没错。
Login类没有userHasAuthenticated的概念。您需要将其作为来自App的道具传递给Login。 -
这是因为你的
Login组件不知道this.userHasAuthenticated(true);是什么意思。它没有userHasAuthenticated的声明。您需要将其传递给该组件 -
我试图通过以下方式做到这一点:
。这不是正确的方法吗? -
那么它附加到
props而不是this。将其从props取下,将其附加到constructor的constructor中的thisprops。
标签: javascript reactjs react-router