select 单击顶部单元格的所有复选框
select all Checkboxes by clicking on the top cell
Сode 在三个文件中。在 setList() 中需要传递一个对象数组来分配,但它们是使用 map 生成的。什么是正确的做法?总的来说,我正在尝试使我的代码适应这个 https://codesandbox.io/s/react-select-all-checkbox-jbub2 但是 Checkbox 的数组被移动到一个单独的文件,而我的是使用 map 生成的。
https://codesandbox.io/s/sweet-butterfly-0s4ff?file=/src/TableBody/TableBody.jsx
1-文件)
let Checkbox = () => {
return (
<div>
<label className={s.checkbox}>
<input className={s.checkbox__input} type="checkbox"/>
<span className={s.checkbox__fake}></span>
</label>
</div>
)
}
2-文件)
const Tablehead = (handleSelectAll, isCheckAll ) => {
return (
<thead className = {s.header}>
<tr className = {s.area}>
<th ><Checkbox name="selectAll" id="selectAll" handleClick={handleSelectAll} isChecked={isCheckAll}/>
</th>
</tr>
</thead>
)
}
3-文件)
const TableBody = ({droplets}) => {
const [isCheckAll, setIsCheckAll] = useState(false);
const [isCheck, setIsCheck] = useState([]);
const [list, setList] = useState([]);
useEffect(() => {
setList();
}, [list]);
const handleSelectAll = e => {
setIsCheckAll(!isCheckAll);
setIsCheck(list.map(li => li.id));
if (isCheckAll) {
setIsCheck([]);
}
};
const handleClick = e => {
const { id, checked } = e.target;
setIsCheck([...isCheck, id]);
if (!checked) {
setIsCheck(isCheck.filter(item => item !== id));
}
};
return (
<>
{droplets.map((droplet, index, id, name ) =>
<tr className={s.area} key={index} >
<td ><Checkbox key={id} name={name} handleClick={handleClick} isChecked={isCheck.includes(id)}/></td>
<td><button type="submit" className={s.button}><Edit /></button></td>
<td><button type="submit" className={s.button}><Trash /></button></td>
</tr>
)
}
</>
)
}
所以这里有几个问题
- 组件
Checkbox
不带任何道具
const Tablehead = (handleSelectAll, isCheckAll)
应该是 const Tablehead = ({ handleSelectAll, isCheckAll })
最重要的是您的 TableHead
和 TableBody
组件都需要此复选框信息,因此您需要将状态从 TableBody
提升到 Table
组件.
此外,您所遵循的示例代码似乎做了很多冗余的事情,这些事情对于实现您的功能来说并不是必需的。只需在每个 droplets
中存储一个 checked
属性 就足够了,并且有两个函数可以切换单个和切换全部。
因此我在您的代码沙箱中进行了上述更改 link。
这里是Link
Сode 在三个文件中。在 setList() 中需要传递一个对象数组来分配,但它们是使用 map 生成的。什么是正确的做法?总的来说,我正在尝试使我的代码适应这个 https://codesandbox.io/s/react-select-all-checkbox-jbub2 但是 Checkbox 的数组被移动到一个单独的文件,而我的是使用 map 生成的。 https://codesandbox.io/s/sweet-butterfly-0s4ff?file=/src/TableBody/TableBody.jsx
1-文件)
let Checkbox = () => {
return (
<div>
<label className={s.checkbox}>
<input className={s.checkbox__input} type="checkbox"/>
<span className={s.checkbox__fake}></span>
</label>
</div>
)
}
2-文件)
const Tablehead = (handleSelectAll, isCheckAll ) => {
return (
<thead className = {s.header}>
<tr className = {s.area}>
<th ><Checkbox name="selectAll" id="selectAll" handleClick={handleSelectAll} isChecked={isCheckAll}/>
</th>
</tr>
</thead>
)
}
3-文件)
const TableBody = ({droplets}) => {
const [isCheckAll, setIsCheckAll] = useState(false);
const [isCheck, setIsCheck] = useState([]);
const [list, setList] = useState([]);
useEffect(() => {
setList();
}, [list]);
const handleSelectAll = e => {
setIsCheckAll(!isCheckAll);
setIsCheck(list.map(li => li.id));
if (isCheckAll) {
setIsCheck([]);
}
};
const handleClick = e => {
const { id, checked } = e.target;
setIsCheck([...isCheck, id]);
if (!checked) {
setIsCheck(isCheck.filter(item => item !== id));
}
};
return (
<>
{droplets.map((droplet, index, id, name ) =>
<tr className={s.area} key={index} >
<td ><Checkbox key={id} name={name} handleClick={handleClick} isChecked={isCheck.includes(id)}/></td>
<td><button type="submit" className={s.button}><Edit /></button></td>
<td><button type="submit" className={s.button}><Trash /></button></td>
</tr>
)
}
</>
)
}
所以这里有几个问题
- 组件
Checkbox
不带任何道具 const Tablehead = (handleSelectAll, isCheckAll)
应该是const Tablehead = ({ handleSelectAll, isCheckAll })
最重要的是您的 TableHead
和 TableBody
组件都需要此复选框信息,因此您需要将状态从 TableBody
提升到 Table
组件.
此外,您所遵循的示例代码似乎做了很多冗余的事情,这些事情对于实现您的功能来说并不是必需的。只需在每个 droplets
中存储一个 checked
属性 就足够了,并且有两个函数可以切换单个和切换全部。
因此我在您的代码沙箱中进行了上述更改 link。
这里是Link