Reputation: 344
I am learning redux/react and I am developing a sample application to understand it, for experiment I am trying to update the checkbox checked property using reducer.
My reducer is as follows.
const check_box_state = (state = false, action) => {
switch(action.type) {
case ActionNames.TOGGLE_CHECKBOX:
return !state;
default:
return state;
}
};
then I am using react-redux connect method to pass this reducer to my component via following code.
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;
Finally my component is as follows.
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;
State of the checkbox start to update successfully and as expected only after the second time I click it, for the first time setState
gets the default state from the reducer and checkbox remains unchecked. I am also using loggerMiddleware from redux-logger and it shows that the state is successfully updated from false to true after the action dispatch but even after that new state I receive is false. What am I doing wrong?
Upvotes: 0
Views: 317
Reputation: 15632
Try this approach (gotten rid off the internal state and now checkbox is controlled using the exising key on redux state):
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);
As per ^^this implementation the redux state is now directly connect
ed to SignInPanel
. So we won't need the code for mapStateToProps
and mapDispatchToProps
to create StateFullSignInPanel
.
Upvotes: 1