componentWillReceiveProps状态与redux状态更新后的呈现状态不同

时间:2016-01-17 17:03:48

标签: redux redux-thunk

首先,所有相关代码(点击该文件的完整源代码的文件名)。

LoginView.js

LoginView = class extends React.Component {
    handleLogin = (email, password) => {
        this.props.authenticationActionCreator.login(email, password);
    };

    componentWillMount () {
        console.log('componentWillMount', 'this.props.isAuthenticated', this.props.isAuthenticated);
    }

    componentWillReceiveProps () {
        console.log('componentWillReceiveProps', 'this.props.isAuthenticated', this.props.isAuthenticated);
    }

    render () {
        let {
            errorMessage,
            isAuthenticating
        } = this.props;

        return <div>
            <p>this.props.isAuthenticated: {this.props.isAuthenticated ? 'true' : 'false'}</p>
            <button onClick={() => {
                this.handleLogin('gajus@applaudience.com', 'nosyte');
            }}>Login</button>
        </div>;
    }
};

authentication.js(减速机)

if (action.type === 'AUTHENTICATION.LOGIN_SUCCESS') {
    return initialState.merge({
        isAuthenticated: true,
        token: action.data.token,
        user: action.data.user
    });
}

authenticationActionCreator.js

authenticationActionCreator.loginSuccess = (token) => {
    let decodedToken;

    // @todo Handle failure to decode token.

    decodedToken = jwtDecode(token);

    localStorage.setItem('token', token);

    return {
        type: 'AUTHENTICATION.LOGIN_SUCCESS',
        data: {
            token,
            user: decodedToken.user
        }
    };
};

流程很简单:

  1. 用户打开页面。
  2. 用户点击调用<button />。{/ li>的authenticationActionCreator.login

    console.log输出为:

    componentWillMount this.props.isAuthenticated true
    action AUTHENTICATION.LOGIN_REQUEST @ 16:52:50.880
    componentWillReceiveProps this.props.isAuthenticated true
    componentWillReceiveProps this.props.isAuthenticated false
    action AUTHENTICATION.LOGIN_SUCCESS @ 16:52:51.975
    

    预期console.log输出为:

    componentWillMount this.props.isAuthenticated true
    action AUTHENTICATION.LOGIN_REQUEST @ 16:52:50.880
    componentWillReceiveProps this.props.isAuthenticated false
    action AUTHENTICATION.LOGIN_SUCCESS @ 16:52:51.975
    componentWillReceiveProps this.props.isAuthenticated true
    

    问题是render具有正确的状态(AUTHENTICATION.LOGIN_SUCCESS之后的状态)和componentWillReceiveProps具有旧状态(AUTHENTICATION.LOGIN_REQUEST之后的状态)。

    我是componentWillReceivePropsrender方法具有相同状态对象的最后一次调用。

    这是:

    • 一个错误
    • 我做错了什么
    • 我的期望是假的

1 个答案:

答案 0 :(得分:3)

我花了所有这些调试跟踪/问题来记住componentWillReceiveProps API是:

componentWillReceiveProps: function(nextProps) {}

换句话说,我的LoginView.js示例应该是:

LoginView = class extends React.Component {
    handleLogin = (email, password) => {
        this.props.authenticationActionCreator.login(email, password);
    };

    componentWillReceiveProps (nextProps) {
        console.log('componentWillReceiveProps', 'nextProps.isAuthenticated', nextProps.isAuthenticated);
    }

    render () {
        let {
            errorMessage,
            isAuthenticating
        } = this.props;

        return <div>
            <p>this.props.isAuthenticated: {this.props.isAuthenticated ? 'true' : 'false'}</p>
            <button onClick={() => {
                this.handleLogin('gajus@applaudience.com', 'nosyte');
            }}>Login</button>
        </div>;
    }
};