带有reactjs的多个复选框



react中有一个复选框子功能组件。它以函数和数据为道具。我必须将项状态传递给父组件,并将它们实际保持在状态数组中。

我希望保持所选项目的状态,并显示它们。我尝试了很多方法,例如在复选框checked={isSelected.includes(item.id)}中,但总是出现错误。

我的checkbox.js是这样的:

function CheckboxList(/*{ onSelectedFilter,data }*/) {
const [isSelected, setSelected] = React.useState({})
const [checked,setChecked]= React.useState()

//---
//temporary (passed as props)
const data = [{id:"1",text:"Product 2"},{id:"2",text:"Product 3"},{id:"3",text:"Product 14"},{id:"6",text:"Product 41"},{id:"7",text:"Prdoduct 1"}]
const onSelectedFilter=(item)=>{
setChecked(!item.checked)
setSelected({...isSelected, [item.id] : checked});
//setSelected([...isSelected,item.id])
console.log(item.id," ", item.text," ",isSelected)
}
//---
React.useEffect(() => {
console.log("checkedItems: ", isSelected);
}, [isSelected]);  
return (
<div className="checkbox-list">
<ul>
{data.map((item) => (
<li key={item.id}>
<label htmlFor={item.text} className="checkbox">
<span className="input">
<input
type="checkbox"
id={item.text}
name="checkbox-list"
value={item.text}
checked={item.selected}
onClick={() => onSelectedFilter(item)}
/>
<span className="control" />
</span>
<span className="label">{item.text}</span>
</label>
</li>
))}
</ul>
</div>
);
}
ReactDOM.render(<CheckboxList />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

我该怎么办?

通常,一种方法可能是(在父组件中(有一个onSelectedFilter函数,看起来像:

function onSelectedFilter(indexToUpdate) {
setItems(prev => [
...prev.slice(0, indexToUpdate),
{ ...prev[indexToUpdate], selected: !prev[indexToUpdate] }, 
...prev.slice(indexToUpdate+ 1)
]);
}

然后,在子组件中,为indexToUpdate提供一个具体值,同时在数组上进行映射:

{
data.map((item, index) => (
<li key={item.id}>
<label htmlFor={item.text} className="checkbox">
<span className="input">
<input
type="checkbox"
id={item.text}
name="checkbox-list"
value={item.text}
checked={item.selected}
onClick={() => onSelectedFilter(index)}
/>
<span className="control" />
</span>
<span className="label">{item.text}</span>
</label>
</li>
));
}

这意味着孩子不需要任何状态。它只是从父对象接受一些道具,其中一个恰好是一个提示父对象更新特定对象的函数。


旁注:您也可以让子组件将item.id或整个item传递回父组件,而不是indexToUpdate(但您需要更改父组件中onSelectedFilter的主体/实现,以使用item.iditem(。

最新更新