以下是问题的.gif记录:http://g.recordit.co/1gy4gyT7jk.gif
我的Dashboard
组件在登录后首次加载时,在控制台中返回以下错误。
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in PlaidLink (at Dashboard.js:51)
in div (at Dashboard.js:44)index.js:1452
尽管出现此错误,但应用程序内的所有内容均正常运行,并且在登录后刷新页面后,错误消失了(有关错误的示例,请参阅.gif)。
这是我的 Login.js
文件。
import React, { Component } from "react";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { loginUser } from "../../actions/authActions";
import classnames from "classnames";
class Login extends Component {
constructor() {
super();
this.state = {
email: "",
password: "",
errors: {}
};
}
componentDidMount() {
// If logged in and user navigates to Login page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
const userData = {
email: this.state.email,
password: this.state.password
};
this.props.loginUser(userData);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div style={{ marginTop: "4rem" }} className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Login</b> below
</h4>
<p className="grey-text text-darken-1">
Don't have an account? <Link to="/register">Register</Link>
</p>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email || errors.emailnotfound
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">
{errors.email}
{errors.emailnotfound}
</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password || errors.passwordincorrect
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">
{errors.password}
{errors.passwordincorrect}
</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Login
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Login.propTypes = {
loginUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ loginUser }
)(Login);
这是我的 Dashboard.js
文件。
import React, { Component } from "react";
import PlaidLink from "react-plaid-link";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { logoutUser } from "../../actions/authActions";
import {
getAccounts,
setAccountsLoading,
addAccount
} from "../../actions/accountActions";
import Transactions from "./Transactions";
class Dashboard extends Component {
componentDidMount() {
this.props.getAccounts();
}
// Logout
onLogoutClick = e => {
e.preventDefault();
this.props.logoutUser();
};
// Add account
handleOnSuccess = (token, metadata) => {
const plaidData = {
public_token: token,
metadata: metadata
};
this.props.addAccount(plaidData);
};
render() {
const { accounts, loading } = this.props.plaid;
let dashboardContent;
if (loading) {
dashboardContent = <p>Loading...</p>;
} else if (accounts === null || accounts.length === 0) {
dashboardContent = (
<div>
<h4>
<b>Welcome,</b> User
</h4>
<p className="flow-text grey-text text-darken-1">
To get started, link your first bank account below
</p>
<PlaidLink
clientName="Mosaic"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
env="sandbox"
product={["auth", "transactions"]}
publicKey="0c3ff69a2efea552189de8b7fbbc0f"
onSuccess={this.handleOnSuccess}
style={{
width: "185px",
letterSpacing: "1.5px",
borderRadius: "3px",
marginTop: "1rem"
}}
>
Link Account
</PlaidLink>
<button
style={{
width: "185px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
onClick={this.onLogoutClick}
className="btn btn-large waves-effect waves-light hoverable red accent-3"
>
Logout
</button>
</div>
);
} else {
dashboardContent = <Transactions accounts={accounts} />;
}
return (
<div className="container">
<div className="row">
<div className="col s12 center-align">{dashboardContent}</div>
</div>
</div>
);
}
}
Dashboard.propTypes = {
logoutUser: PropTypes.func.isRequired,
getAccounts: PropTypes.func.isRequired,
addAccount: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
plaid: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
plaid: state.plaid
});
export default connect(
mapStateToProps,
{ logoutUser, getAccounts, setAccountsLoading, addAccount }
)(Dashboard);
这是由于我的组件引起的问题,还是与我的Redux动作和reducer的触发方式有关?
答案 0 :(得分:4)
您可以尝试将this.setState = (state,callback)=>{
return;
};
写入componentWillUnmount
答案 1 :(得分:0)
选项1:使用 withRouter HOC
import { withRouter } from 'react-router-dom';
...
export default withRouter(Login)
选项2:使用重定向
<Redirect to='/dashboard' />