Redux / React在第一次调度时没有返回更新的状态

时间:2016-11-29 14:22:58

标签: reactjs redux

我正在学习redux / react,我正在开发一个示例应用程序来理解它,实验我试图使用reducer更新checkbox复选属性。

我的减速机如下。

const check_box_state = (state = false, action) => {
switch(action.type) {
    case ActionNames.TOGGLE_CHECKBOX:
        return !state;
    default:
        return state;
}
};

然后我使用react-redux connect方法通过以下代码将此reducer传递给我的组件。

const StateFullSignInPanel = connect(
function mapStateToProps(state) {
    return {redux_state: state};
},
function mapDispatchToProps(dispatch) {
    return {
        toggle_check_box: (previous_state) => dispatch(toggleCheckbox(previous_state))
    }
}
)(SignInPanel);

export default StateFullSignInPanel;

最后我的组件如下。

class SignInPanel extends Component {

    constructor(props) {
        super(props);
        this.state = {
            checkbox_state: this.props.redux_state.generic_reducers.check_box_state
        };
        this.handleRememberMeState = this.handleRememberMeState.bind(this);
        this.handleSignInClick = this.handleSignInClick.bind(this);
    }

    handleRememberMeState() {
        let previous_checkbox_state = this.state.checkbox_state;
        this.props.toggle_check_box(previous_checkbox_state);
        let new_checkbox_state = this.props.redux_state.generic_reducers.check_box_state;
        this.setState({
            checkbox_state: new_checkbox_state
        });
    }

    handleSignInClick() {
    }

    render() {
        return <div className="ui card sign_in_card">
            <div className="ui input input_fields">
                <input type="text" placeholder="Email or username"/>
            </div>
            <div className="ui input input_fields">
                <input type="text" placeholder="Password"/>
            </div>
            <div className="ui checkbox remember_me_checkbox">
                <input
                    type="checkbox"
                    id="remember_me"
                    onChange={this.handleRememberMeState}
                    checked={this.state.checkbox_state}
                />
                <label htmlFor="remember_me">Remember me</label>
            </div>
            <div className="sign_in_button">
                <button className="ui green button" onClick={this.handleSignInClick}>
                    Sign in
                </button>
            </div>
        </div>
    }
}

export default SignInPanel;

复选框的状态开始成功更新并且仅在我第二次单击它之后才会按预期更新,第一次setState从reducer获取默认状态并且复选框保持未选中状态。我也使用来自redux-logger的loggerMiddleware,它表明在动作调度后状态从false成功更新为true,但即使在我收到的新状态之后也是假的。我做错了什么?

1 个答案:

答案 0 :(得分:1)

尝试这种方法(摆脱内部状态,现在使用redux状态的exising键控制复选框):

import { toggleCheckbox } from './actions';

class SignInPanel extends Component {

    constructor(props) {
        super(props);
        this.handleRememberMeState = this.handleRememberMeState.bind(this);
        this.handleSignInClick = this.handleSignInClick.bind(this);
    }

    handleRememberMeState() {
        this.props.toggle_check_box(this.props.check_box_state);
    }

    handleSignInClick() {
        // ...
    }

    render() {
        return <div className="ui card sign_in_card">
            <div className="ui input input_fields">
                <input type="text" placeholder="Email or username"/>
            </div>
            <div className="ui input input_fields">
                <input type="text" placeholder="Password"/>
            </div>
            <div className="ui checkbox remember_me_checkbox">
                <input
                    type="checkbox"
                    id="remember_me"
                    onChange={this.handleRememberMeState}
                    checked={this.props.check_box_state}
                />
                <label htmlFor="remember_me">Remember me</label>
            </div>
            <div className="sign_in_button">
                <button className="ui green button" onClick={this.handleSignInClick}>
                    Sign in
                </button>
            </div>
        </div>
    }
}

export default connect(
  (state) => ({ check_box_state: redux_state.generic_reducers.check_box_state }),
  { toggle_check_box: toggleCheckbox }
)(SignInPanel);

根据^^这个实现,redux状态现在直接connectSignInPanel。因此,我们不需要mapStateToPropsmapDispatchToProps的代码来创建StateFullSignInPanel