【问题标题】:componentWillReceiveProps state is different from render state after redux state updatecomponentWillReceiveProps 状态与 redux 状态更新后的渲染状态不同
【发布时间】:2016-04-22 19:32:54
【问题描述】:

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

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. 用户点击调用authenticationActionCreator.login&lt;button /&gt;

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 之后的状态)。

我是最后一次调用 componentWillReceiveProps 以拥有与 render 方法相同的状态对象。

这是:

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

?

【问题讨论】:

    标签: redux redux-thunk


    【解决方案1】:

    我写了所有这些调试跟踪/问题来记住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>;
        }
    };
    

    【讨论】:

    • 你知道为什么吗?是因为 componentWillReceiveProps 甚至在 props 更新之前就通过更新的道具传递了吗?感谢您留下答案。我也没有先检查 API,而是花了几个小时试图弄清楚发生了什么。
    猜你喜欢
    • 1970-01-01
    • 2019-05-07
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 2016-08-31
    • 2023-03-13
    相关资源
    最近更新 更多