简体   繁体   中英

how to implement checkbox in react (checked and unchecked functionality)?

I am trying to implement checkbox in react but I am facing a issue while checking and uncheck of checkbox.

I tried to implement onchange handler .

onChange={() => {
                    // first approch
                    //  i.checked = !i.checked;
                    // setObj({ ...i});

                    // second approach
                    setObj({ ...i, checked: !i.checked });
                    setTimeout(ab, 2000);
                  }}

so I used two approach

In First approach i changed the toggle the checked property and then create new reference which is working fine

 i.checked = !i.checked;
   setObj({ ...i});

In second approach I created a new object or reference with toggle of checked property but this is not working why

{ ...i, checked: !i.checked }

why my first and second approach is different ?

here is my code

https://codesandbox.io/s/lucid-fire-cxp9c?file=/src/child.js:362-666

import React from "react";
export default function Child({ data, ab }) {
  const [obj, setObj] = React.useState(null);

  return (
    <>
      {data &&
        data.map((i, idx) => {
          return (
            <ul key={idx}>
              <li>
                <input
                  type="checkbox"
                  checked={i.checked}
                  onChange={() => {
                    // first approch
                    //  i.checked = !i.checked;
                    // setObj({ ...i});

                    // second approach
                    setObj({ ...i, checked: !i.checked });
                    setTimeout(ab, 2000);
                  }}
                />
                {i.label}
              </li>
              {i.childrens && i.childrens.length > 0 ? (
                <Child data={i.childrens} ab={ab} />
              ) : null}
            </ul>
          );
        })}
    </>
  );
}

any suggestion ...!!?

Okay, so mixing the state and props makes it a little messy. I did some refactoring and added in a little recursion for the tree of nested values you're using. I added comments above the changes I made.

var data = [/* your array of data */]


// recursive function to find the value in the tree
const setChecked = (data, label) => {
  if (!data || data.length === 0) return [];
  // grab the first element
  const [current, ...rest] = data;

  // if it's found, plop the element back into place with
  // check changed and dump in the rest of the elements
  if (current.label === label) {
    return [
      {
        ...current,
        checked: !current.checked,
        childrens: current.childrens.map((child) => ({
          ...child,
          checked: !current.checked
        }))
      },
      ...rest
    ];
  }

  // re-slot the element and recursively move
  // through the remaining siblings
  return [
    {
      ...current,
      childrens:
        current.childrens.length > 0
          ? setChecked(current.childrens, label)
          : current.childrens
    },
    ...setChecked(rest, label)
  ];
};

export default function App() {
  const [state, setState] = React.useState(data1);

  const handleChange = (data) => {
    setState(setChecked(state, data.label));
  };

  const ab = () => {
    console.log(JSON.stringify(state));
  };

  return (
    <div className="App">
      <Child data={state} ab={ab} handleChange={handleChange} />
    </div>
  );
}

// added the onChange handler to lift the state to the parent
export default function Child({ data, ab, onChange }) {
  return (
    <>
      {data &&
        data.map((i, idx) => {
          return (
            <ul key={idx}>
              <li>
                <input
                  type="checkbox"
                  checked={i.checked}
                  onChange={() => {
                    onChange(i);
                    setTimeout(ab, 2000);
                  }}
                />
                {i.label}
              </li>
              {i.childrens && i.childrens.length > 0 ? (
                <Child data={i.childrens} ab={ab} onChange={onChange} />
              ) : null}
            </ul>
          );
        })}
    </>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM