我有一个表格组件,每行和标题上都有复选框。除此之外,每行都有从对象dataSet
数组中呈现的名字,姓氏和年龄。我想要一种能够通过单击标题中的复选框来选择/取消选择所有行并捕获所有数据的方法。
同时,我还希望能够选择/取消选择各个行。同样,我要捕获所选每一行的数据。
以下是组件:
class Table extends React.Component {
render() {
return(
<table style={{width:"100%"}}>
<tr>
<th><input type="checkbox" name="name1" /></th>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tbody>{this.renderRow()}</tbody>
</table>
);
}
renderRow = () => {
const dataSet = [
{
FirstName: "Bob",
LastName: "Ross",
Age: 50
},
{
FirstName: "John",
LastName: "Doe",
Age: 20
},
{
FirstName: "Jane",
LastName: "Doe",
Age: 30
}
];
return dataSet.map((item) => {
return (
<tr>
<td><input type="checkbox" name="name1" /></td>
<td>{item.FirstName}</td>
<td>{item.LastName}</td>
<td>{item.Age}</td>
</tr>
)
})
}
};
以下是该组件的运行版本:https://codepen.io/anon/pen/exgeBg
答案 0 :(得分:2)
首先,您需要为每一项赋予某种id
,以便您可以将它们彼此区分开,并在映射它们时为其赋予key
:
const dataSet = [
{
id: 45612,
FirstName: "Bob",
LastName: "Ross",
Age: 50
},
{
id: 6542,
FirstName: "John",
LastName: "Doe",
Age: 20
},
{
id: 7837,
FirstName: "Jane",
LastName: "Doe",
Age: 30
}
];
添加密钥:
return (
<tr key={item.id}>
要知道选择了哪个项目,您需要通过复选框的onClick
功能发送该项目本身:
<td><input type="checkbox" name="name1" onClick={this.rowSelected(item)}/></td>
您的类中的接收函数将声明如下,可以接收该项目,然后可以接收click事件:
rowSelected = rowData => ev => {
棘手的部分现在将状态设置为包含每个选定的行。如果复选框被选中,我们将把该项目添加到先前选择的项目中,否则,我们将从数组中过滤出该项目:
rowSelected = rowData => ev => {
this.setState(prev => ({
selection: ev.target.checked ? [...prev.selection, rowData] : prev.selection.filter(item => item.id !== rowData.id)
}))
}
您现在可以访问this.state.selection
完整代码:
class Table extends React.Component {
rowSelected = rowData => ev => {
this.setState(prev => ({
selection: ev.target.checked ? [...prev.selection, rowData] : prev.selection.filter(item => item.id !== rowData.id)
}))
}
render() {
return (
<table style={{ width: "100%" }}>
<tr>
<th><input type="checkbox" name="name1" /></th>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tbody>{this.renderRow()}</tbody>
</table>
);
}
renderRow = () => {
const dataSet = [
{
id: 45612,
FirstName: "Bob",
LastName: "Ross",
Age: 50
},
{
id: 6542,
FirstName: "John",
LastName: "Doe",
Age: 20
},
{
id: 7837,
FirstName: "Jane",
LastName: "Doe",
Age: 30
}
];
return dataSet.map((item) => {
return (
<tr key={item.id}>
<td><input type="checkbox" name="name1" onClick={this.rowSelected(item)}/></td>
<td>{item.FirstName}</td>
<td>{item.LastName}</td>
<td>{item.Age}</td>
</tr>
)
})
}
};
编辑
要创建“全选”按钮,您将必须执行另一个功能:
selectAll = ev => {
this.setState(prev => ({ selction: prev.selection.length ? [] : dataSet }))
}
如果先前选择中已经包含元素,则将其清空,如果没有任何元素,则将其替换为您的整个数据集;您将需要将其存储在其他地方,例如课外或this.dataset
中。
如果您希望自动选中复选框,则需要检查对应项是否在您的状态下,以设置其checked
道具(IIRC):
<input type="checkbox" name="name1" onClick={this.rowSelected(item)} checked={this.state.selection.some(slc => slc.id === item.id)}/>
答案 1 :(得分:1)
更改之处
首先,您需要保留复选框的状态,可以在代码的这一部分中设置默认值,以防您希望某些复选框开始被选中:
state = {
header: false,
fields: [false, false, false, false]
}
现在,当某些复选框发生更改时,您需要处理程序。
有很多方法可以做到这一点,但为简化起见,我使用了两个功能
changeCheckBoxFields
可以获取要更改的复选框的索引,changeAllCheckBox
可以更改标题的复选框的值,而所有其他复选框将具有与他相同的值
在CodePen中运行的完整代码
完整代码:
class Table extends React.Component {
state = {
header: false,
fields: [],
dataSet: []
}
changeAllCheckBox = () => {
let {
header,
fields,
} = this.state
let newHeader = !header
let newFields = fields.map((f) => {
return {
checked: newHeader,
data: f.data
}
})
this.setState({
fields: newFields,
header: newHeader
})
}
changeCheckBoxFields = (item, index) => {
let newState = this.state.fields
newState[index] = {
check: !newState[index],
data: item
}
this.setState({fields: newState})
}
componentDidMount() {
const dataSet = [
{
FirstName: "Bob",
LastName: "Ross",
Age: 50
},
{
FirstName: "John",
LastName: "Doe",
Age: 20
},
{
FirstName: "Jane",
LastName: "Doe",
Age: 30
}
];
let fields = dataSet.map((d, i) => {return {checked: false} } )
this.setState({
dataSet: dataSet,
fields: fields,
})
}
render() {
return(
<table style={{width:"100%"}}>
<tr>
<th><input type="checkbox" name="name1" onChange={this.changeAllCheckBox} /></th>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tbody>{this.renderRow()}</tbody>
</table>
);
}
renderRow = () => {
return this.state.dataSet.map((item, index) => {
return (
<tr key={index}>
<td>
<input type="checkbox" name="name1" onChange={() => this.changeCheckBoxFields(item, index)} checked={this.state.fields[index].checked} />
</td>
<td>{item.FirstName}</td>
<td>{item.LastName}</td>
<td>{item.Age}</td>
</tr>
)
})
}
};
有关反应输入Reactjs Documentation
的更多信息编辑: 仅检查完整的代码现在,您可以根据需要拥有任意多的行,可以获取数据,并且是否进行检查。组件