[英]Separate checkbox for each table row in React.js
我有一个功能组件,它返回一个包含许多行的表,如下所示:
import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
function Table({ data }) {
const [checked, setChecked] = useState(false);
const handleChange = (event) => {
setChecked(event.target.checked);
};
return (
// Some table head code
<TableBody>
{data.map((row) => (
<TableRow key={row.id}>
<TableCell align="left">
<Checkbox
checked={checked}
onChange={handleChange}
inputProps={{ "aria-label": "primary checkbox" }}
/>
</TableCell>
</TableRow>
// More table row code here
))}
</TableBody>
);
}
每行都有一个复选框。 问题是当我点击一个复选框时,其他行上的所有其他复选框都被选中。 我应该如何 go 关于这个。
出于某种原因,我尝试了这个并且它有效:
import React from "react";
import Checkbox from "@material-ui/core/Checkbox";
function Table({ data }) {
const [checked, setChecked] = useState({});
const handleChange = (event, row) => {
setChecked({ id: row.id, check: event.target.checked });
};
return (
// Some table head code
<TableBody>
{data.map((row) => (
<TableRow key={row.id}>
<TableCell align="left">
<Checkbox
checked={checked}
onChange={(e) => handleChange(e, row)}
inputProps={{ "aria-label": "primary checkbox" }}
/>
</TableCell>
</TableRow>
))}
</TableBody>
);
}
简而言之,发生这种情况的原因是您传递了相同的 state 并将处理程序 function 更改为每个 input 。 如果我们要去掉函数的引用层和 state 值,那么这就是您当前在代码中的内容
.map => new Map([
<input
type="checkbox"
checked={false}
onChange={(event) => set(event.target.checked)}
/>,
<input
type="checkbox"
checked={false}
onChange={(event) => set(event.target.checked)}
/>
// ... and so on for each and every one of them
])
所以如果你选中一个,它会改变所有的
您需要为每个复选框声明一个单独的 state,或将它们合并为一个大型简化的 state 复选框。 无需手动声明每个复选框的最简单方法是动态生成它们并将它们reduce
为单个 state:
import React, { useState, ChangeEvent } from 'react'
// example of what gets passed
const data = [
{ id: 0 },
{ id: 1 },
{ id: 2 },
{ id: 3 },
]
// Checkbox component
const Table ({ data }) => {
// in case 'data' is async you'll need to use useEffect or useCallback
// generates individual state for each data row
const initialState = data.reduce(
(state, current) => (
Object.assign(state, { [current.id]: false })
),
{}
) // {0: false, 1: false, 2: false, 3: false}
const [checkboxes, setCheckboxes] = useState(initialState)
}
现在我们已经处理好了 state,我们只需要编写我们的onChange
处理程序。
const handleToggle = (event: ChangeEvent<HTMLInputElement>) => {
const { checked, name } = event.target
setCheckboxes(prevState => ({
...prevState,
[name]: checked,
}))
}
并产生您的回报:
return (
<div className="App">
{/* in case your id does not match index, use Object.entries instead */}
{Object.values(checkboxes).map((isChecked, index) => (
<TableRow key={index}>
<TableCell align="left>
<Checkbox
name={index}
checked={isChecked}
onChange={handleToggle}
/>
</TableCell>
</TableRow>
))}
</div>
);
这是一个有效的代码框示例:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.