In my component I have checkboxes. When I click on them I want save selected checkbox in redux state and update my component so selected checkbox should shown as checked. So this is my component:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {selectIngredient} from '../actions';
class Ingredient extends Component {
constructor(props) {
super(props)
this.isSelected = this.isSelected.bind(this);
this.handleCheckbox = this.handleCheckbox.bind(this);
}
handleCheckbox(e) {
const value=e.target.value;
this.props.selectIngredient(value);
}
isSelected(id) {
return (this.props.selectedIngredients.indexOf(id) > -1)
}
render() {
return (
<div className="container">
<div className="form-check checkbox">
<label className="form-check-label">
<input checked={this.isSelected(1)}
className="form-check-input"
onClick={this.handleCheckbox}
type="checkbox" value="1" />
1
</label>
</div>
<div className="form-check checkbox">
<label className="form-check-label">
<input checked={this.isSelected(2)}
className="form-check-input"
onClick={this.handleCheckbox}
type="checkbox" value="2" />
2
</label>
</div>
<div className="form-check checkbox">
<label className="form-check-label">
<input checked={this.isSelected(3)}
className="form-check-input"
onClick={this.handleCheckbox}
type="checkbox" value="3" />
3
</label>
</div>
</div>
);
}
}
function mapStateToProps(state, ownProps){
const {selectedIngredients} = state;
return {selectedIngredients}
}
export default connect(mapStateToProps,{selectIngredient})(Ingredient);
And this is action/index.js
import {SELECT_INGREDIENT} from "../constants";
export function selectIngredient(selected){
const action = {
type: SELECT_INGREDIENT,
selected
}
return action;
}
And here is reducer:
import {SELECT_INGREDIENT} from "../constants";
export default (state={selectedIngredients:[]}, action)=>{
let stateBefore = Object.assign({},state);
switch(action.type){
case SELECT_INGREDIENT:
const {selected} = action;
stateBefore['selectedIngredients'].push(+selected);
return stateBefore
default:
return state;
}
}
When I click on checkboxes nothing changes, they stay empty. Component is not updating. But redux updating its state. I thought if redux state is updating so should the component and its checkboxes. Is it wrong?
Please help me figure out how to make this work. Thank you
The answer given in the comments below:
in your reducer return { ...state, selectedIngredients: [...state.selectedIngredients, action.selected] }
This is a mutation:
let stateBefore = Object.assign({},state);
...
stateBefore['selectedIngredients'].push(+selected);
You are shallowly copying the state object but you still mutate the selectedIngredients because it is copied by reference so you are still modifying the existing selectedIngredients object.
Check the first answer to following issue https://github.com/reactjs/redux/issues/1769
use object spread operator:
case SELECT_INGREDIENT:
return {
...state,
selectedIngredients: [...state.selectedIngredients, action.selected],
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With