Home > Software design >  Toggle checkbox state is not change React reducer
Toggle checkbox state is not change React reducer

Time:04-10

I try to change the checkbox state on change, but it doesn't change. It looks like this picture. Here is my InitialState

const initialState = {
  isLoading: false,
  showAlert: false,
  products: [],
  totalProducts: 0,
  numOfPages: 1,
  select: false,
};

Here is my ContextCode

  const toggleProduct = (e) => {
    const id = e.target.id;
    dispatch({ type: TOGGLE_PRODUCT, payload: { id } });
  };

Reducer

if (action.type === TOGGLE_PRODUCT) {
    return {
      ...state,
      products: state.products.map((product) => {
        if (product._id === action.payload.id) {
          return { ...product, select: !state.select };
        } else {
          return product;
        }
      }),
    };
  }

And how to look input

   <input
        type='checkbox'
        name={name}
        defaultChecked={select}
        id={_id}
        onChange={toggleProduct}
      />

If input simply checked it doesn't work, input isn't chosen, but if defaultChecked I can choose input but state isn't changed (please look at the screenshot). Thanks in advance

CodePudding user response:

@jsN00b stated correctly in the comment, all four products' check state are controlled by a single one controlled element, namely the select key, but normally, every product should have it's own select attribute, like this:

const initialState = {
  isLoading: false,
  showAlert: false,
  products: [ 
              // hard code the data for now
              {_id: 1, productName: "productOne", select: false},
              {_id: 2, productName: "productTwo", select: false},
              {_id: 3, productName: "productThree", select: false},
            ],
  totalProducts: 0,
  numOfPages: 1
  // select: false, ⬅ we don't need select in here now
};

// reducer
if (action.type === TOGGLE_PRODUCT) {
    return {
      ...state,
      products: state.products.map((product) => {
        if (product._id === action.payload.id) {
          return { ...product, select: !product.select }; // only toggle select for THE product
        } else {
          return product;
        }
      }),
    };
  }
  • Related