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.