如果我在React Native中有一个List并且每个列表项都有一个复选框,我怎样才能获得所有这些复选框的状态?
现在我正在使用这个
{
this.props.data.allLogs.map((r) => {
return (
<ListItem
key={r.id}
title={r.logDate}
onPress={() => this.toggle(r.id)}
subtitle={
<CheckBox
title={`start: ${r.startedAtOdometerReading} -> end: ${r.endedAtOdometerReading}`}
checked={this.state.checkboxes[r.id]}
onPress={() => this.toggle(r.id)}
onIconPress={() => this.toggle(r.id)}
/>
}
/>
);
})
}
toggle(id) {
let checkboxes = this.state.checkboxes;
checkboxes[id] = !this.state.checkboxes[id];
this.setState({checkboxes});
}
它的工作原理(复选框打开和关闭没有问题),但当我注销this.state.checkboxes时,我得到一个空数组......
答案 0 :(得分:3)
首先,请确保您不要直接更改状态,因为这在React中是一种不好的做法,您应该将toggle
功能更改为此
toggle(id) {
this.setState({checkboxes: {...this.state.checkboxes, [id]: !this.state.checkboxes[id]}});
}
现在回答你的问题 - 如果没有剩下的代码就很难分辨,但你可以像这样重构它
class CheckboxesList extends React.Component {
//...
renderListElements = () => {
const { checkboxes } = this.state
this.props.data.allLogs.map((r) => {
return (
<CheckboxListItem
key={r.id}
toggle={this.toggle}
checked={checkboxes[r.id]}
r={r} />
);
})
}
toggle = (id, checked) => {
this.setState({ checkboxes: { ...this.state.checkboxes, [id]: checked } })
}
}
和您的列表项
class CheckboxListItem extends React.Component {
//...
state = {
checked: false
}
componentDidMount() {
const { checked } = this.props
this.setState({ checked })
}
onToggle = () => {
const { r } = this.props
const newChecked = !this.state.checked
this.setState({ checked: newChecked }, () => {
this.props.toggle(r.id, newChecked)
})
}
render() {
const { r } = this.props
const { checked } = this.state
return (
<ListItem
title={r.logDate}
onPress={this.onToggle}
subtitle={
<CheckBox
title={`start: ${r.startedAtOdometerReading} -> end: ${r.endedAtOdometerReading}`}
checked={checked}
onPress={this.onToggle}
onIconPress={this.onToggle}
/>
}
/>
)
}
}
确保您还重构Checkbox以在其状态中使用checked
prop,以便在checked
更改时更新
答案 1 :(得分:1)
我猜你得到一个空数组的原因是因为列表已卸载,其状态被清除。
答案 2 :(得分:1)
我改为一个字符串数组,现在一切正常。这个解决方案也更好用,因为我可以设置一个按钮来检查&#34;列表中的所有项目或&#34;删除&#34;它们都只是将所有ID添加到数组中,或者全部删除它们。
{
this.props.data.allLogs.map((r) => (
<ListItem
key={r.id}
title={`${getReadableDate(r.logDate, true)}`}
subtitle={
<CheckBox
title={`start: ${r.startedAtOdometerReading} -> end: ${r.endedAtOdometerReading}`}
checked={this.state.checkboxes && this.state.checkboxes.includes(r.id)}
onPress={() => this.toggle(r.id)}
onIconPress={() => this.toggle(r.id)}
/>
}
/>
))
}
toggle(id) {
let checkboxes = this.state.checkboxes;
if(checkboxes && checkboxes.includes(id)){
const index = checkboxes.indexOf(id);
checkboxes.splice(index, 1);
} else {
checkboxes = checkboxes.concat(id);
}
this.setState({checkboxes});
}