index.js:1335警告:setState(...):在现有状态转换期间无法更新(例如在`render`或其他组件的构造函数中)。

时间:2016-11-15 15:04:56

标签: javascript reactjs

添加react-ladda插件后出现问题。

这是我的代码:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Field, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import LaddaButton, { EXPAND_RIGHT } from 'react-ladda';
import { signinUser } from '../../actions/AuthActions';

class Login extends Component {
    constructor(props) {
        super(props);
        this.state = { loading: false };
    }

    componentDidMount() {
        ReactDOM.findDOMNode(this.refs.email).focus();
    }

    handleFormSubmit({ username, password }) {
        this.setState({ loading: true });
        this.props.signinUser({ username, password });
    }

    renderAlert() {
        this.setState({ loading: false });

        if (this.props.errorMessage) {
            const message = this.props.errorMessage;
            return (
                <div className="alert alert-danger">
                    <strong>{message.title}</strong>
                    <ul>
                        <li>{message.message}</li>
                    </ul>
                </div>
            );
        }
    }

    render() {
        const { handleSubmit } = this.props;
        return (
            <div>
                <div className="account-pages login-pages" />
                <div className="clearfix" />
                <div className="wrapper-page">

                    <div className="m-t-40 card-box">
                        <div className="text-center">
                            <h4 className="text-uppercase font-bold m-b-0">Sign In</h4>
                        </div>
                        <div className="panel-body">
                            {this.renderAlert()}

                            <form
                                className="form-horizontal m-t-20" name="form"
                                onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}
                                >
                                <div className="form-group">
                                    <Field
                                        className="form-control input-lg" component="input"
                                        type="text" name="email" ref="email" placeholder="email"
                                        />
                                </div>
                                <div className="form-group">
                                    <Field
                                        className="form-control input-lg" component="input" type="password"
                                        name="password" placeholder="password"
                                        />
                                </div>

                                <div className="form-group text-center m-t-20">
                                    <LaddaButton
                                        action="submit"
                                        loading={this.state.loading}
                                        data-style={EXPAND_RIGHT}
                                        className="btn btn-custom btn-bordred btn-block waves-effect waves-light"
                                        >
                                        SIGN IN
                                </LaddaButton>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>

        );
    }
}

function mapStateToProps(state) {
    return {
        errorMessage: state.auth.error
    };
}

Login = reduxForm({
    form: 'loginForm',
})(Login);

export default connect(mapStateToProps, { signinUser })(Login);

当我运行它时,我的控制台会显示index.js:1335 Warning: setState(...): Cannot update during an existing state transition (such as within渲染or another component's constructor).并且应用程序崩溃。

任何解决方案?

2 个答案:

答案 0 :(得分:1)

您正在renderAlert设置状态,然后在render中使用它。您不应该在render方法中设置状态。我不确定您的逻辑,但isLoadingfalse,您在用户提交表单时正在更改它。一旦页面呈现(来自另一个视图),将其更改为true是没有意义的

答案 1 :(得分:1)

正确,你不能改变渲染中的状态,因为这会导致重新渲染,这将再次改变状态......然后你将有一个无限循环。 :(

如果你想设置一个加载变量,并希望在收到新道具后更新变量,你可以使用componentDidUpdate(),然后你可以检查某件事是否成功,并切换变量。

例如,假设您要检查是否有新错误,那么您可以在那里设置加载变量,或者您可以在更新时检查加载变量是否为真,然后将其设置为false。

componentDidUpdate(prevProps, prevState) {
    // if the component has updated and loading is still set to true, set it to false    
    if (this.state.loading) {
        this.setState({ loading: false })
    }

    // or if you want to check if the error prop has changed and reset loading
    if (this.props.errorMessage !== prevProps.errorMessage) {
        this.setState({ loading: false })
    }
}

详细了解componentDidUpdate(和其他React Lifecycle方法)here