Skip to content
Advertisement

facing issue to store value in state and 3rd time state is not updating in react js

I am trying to get value from the radio button the problem is I can get the values but when I tried to store on my state it only updates 2 times after the 3rd time when I try to update the state it is not updating.

Radio buttons code.

              <li>
                <label className="container_radio">
                  Small
                  <span>+ $5</span>
                  <input
                    type="radio"
                    required
                    onChange={(e) => handleChange(e, product)}
                    defaultValue={5}
                    name={"size"}
                  />
                  <span className="checkmark"></span>
                </label>
                <label className="container_radio">
                  Medium
                  <span>+ $10</span>
                  <input
                    type="radio"
                    required
                    onChange={(e) => handleChange(e, product)}
                    defaultValue={10}
                    name={"size"}
                  />
                  <span className="checkmark"></span>
                </label>
                <label className="container_radio">
                  Large
                  <span>+ $15</span>
                  <input
                    type="radio"
                    required
                    onChange={(e) => handleChange(e, product)}
                    defaultValue={15}
                    name={"size"}
                  />
                  <span className="checkmark"></span>
                </label>
              </li>

I am trying to achieve output something like this

[{title: 'Barnes Chapman', options:{Medium size: '5.00' } }]

My ui:

enter image description here

My function: problem is here if (isExist) { isExist.options = { ...isExist.options, [name]: value, }; return prevValue; for this code the state is not updaing unlimited time.

  const handleChange = (e, product) => {
    // Destructuring
    const { name, value, checked } = e.target;

    console.log(`${value} is ${checked} `);

    // Case 1 : The user checks the box
    if (checked) {
      setProductInfo((prevValue) => {
        const isExist = prevValue.find((item) => item.title === product.title);
        if (isExist) {
          isExist.options = {
            ...isExist.options,
            [name]: value,
          };
          return prevValue;
        } else {
          return [
            ...prevValue,
            {
              title: product.title,
              options: { [name]: value },
            },
          ];
        }
      });
    }

    // Case 2  : The user unchecks the box
    else {
      setProductInfo(productinfo.filter((e) => e.title !== name));
    }
  };

Advertisement

Answer

There are few problems in your code.

1. Don’t change state variable directly.

In the following code, you are trying to change state variable directly. This may result unexpected result.

const isExist = prevValue.find((item) => item.title === product.title);
if (isExist) {
  isExist.options = {
    ...isExist.options,
    [name]: value,
  };
  return prevValue;
}

You can read more about it.

Why can’t I directly modify a component’s state

2. In this code, you should compare array item by title instead of name. Because you are using title.

    // Case 2  : The user unchecks the box
    else {
      setProductInfo(productinfo.filter((e) => e.title !== name));
    }

3. Updated code based on your code in codesandbox

import { useState } from "react";
import Select from "react-select";
import "./styles.css";

export default function App() {
  const [productinfo, setProductInfo] = useState([]);

  const handleChange = (e, product) => {
    // Destructuring
    const { name, value, checked } = e.target;

    console.log(`${value} is ${checked} ${product.title}`);

    // Case 1 : The user checks the box
    if (checked) {
      setProductInfo((prevValue) => {
        const newValue = prevValue ? [...prevValue] : [];
        const isExist = newValue.find((item) => item.title === product.title);
        if (isExist) {
          isExist.options = {
            ...isExist.options,
            [name]: value,
          };
          return newValue;
        } else {
          return [
            ...newValue,
            {
              title: product.title,
              options: { [name]: value },
            },
          ];
        }
      });
    }

    // Case 2  : The user unchecks the box
    else {
      setProductInfo(productinfo.filter((e) => e.title !== product.title));
    }
  };
  console.log(productinfo, "state");

  return (
    <div className="App">
      <ul className="clearfix">
        {/* {product.options.map((option, i) => {
                return ( */}
        <li>
          <label className="container_radio">
            Small
                  <span>+ $5</span>
            <input
              type="radio"
              required
              onChange={(e) => handleChange(e, { title: "title" })}
              defaultValue={5}
              name={"size"}
            />
            <span className="checkmark"></span>
          </label>
          <label className="container_radio">
            Medium
                  <span>+ $10</span>
            <input
              type="radio"
              required
              onChange={(e) => handleChange(e, { title: "title" })}
              defaultValue={10}
              name={"size"}
            />
            <span className="checkmark"></span>
          </label>
          <label className="container_radio">
            Large
                  <span>+ $15</span>
            <input
              type="radio"
              required
              onChange={(e) => handleChange(e, { title: "title" })}
              defaultValue={15}
              name={"size"}
            />
            <span className="checkmark"></span>
          </label>
        </li>
        {/* ); */}
        {/* // })} */}
      </ul>
    </div>
  );
}

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement