5

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] }

1 Answer 1

2

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],
  }
Sign up to request clarification or add additional context in comments.

6 Comments

thank you. I'm actually using component state approach before, but now trying to move it to redux
I thought if redux state is updating so should the component and its checkboxes.
try not mutating state as referenced in this issue github.com/reactjs/redux/issues/585
in your reducer return { ...state, selectedIngredients: [...state.selectedIngredients, action.selected] }
I use stateBefore = Object.assign({},state); to clone state and then work with this new object..is this still mutating ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.