我已经从 NativeBase 导入了 CheckBox。单击复选框时,它会调用toggleCheckBox函数以在数组中添加或删除item.ids,并根据数组的内容将标志设置为true或false。
我可以看到,toggleCheckBox 函数工作正常,它正确设置了具有项目 id 的数组,并且单击复选框时该标志也很好。但是,尽管正确调用了切换函数,但单击复选框时不会选中 ListItem 内的复选框。
我还注意到,单击复选框后会打印列表正上方的日志“MS CB2:”,但不会打印列表“MS insideList :”内的日志。我假设在调用toggleCheckBox 函数后不会呈现List。 这是代码:
class MSScreen extends Component {
constructor(props){
super(props);
//this.toggleCheckbox = this.toggleCheckbox.bind(this);
this.state = {
isLoading: true,
checkboxes : [],
plans: {},
};
}
componentDidMount(){
console.log("MS inside componentDidMount");
fetch('http://hostname:port/getData')
.then((response) => {console.log('response'); return response.json();})
.then((responseJson) => {console.log('responseData: '+responseJson); this.setState({isLoading : false, plans : responseJson}); return;})
.catch((err) => {console.log(err)});
}
toggleCheckbox(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});
console.log("MS check a4: "+checkboxes && checkboxes.includes(id))
}
render() {
if (this.state.isLoading) {
return <View><Text>Loading...</Text></View>;
}
const plans = this.state.plans;
const { params } = this.props.navigation.state.params;
const checkboxes = this.state.checkboxes;
console.log("MS CB1: "+checkboxes)
return (
<Container>
<Content>
<View>
{console.log("MS CB2: "+checkboxes)}
<List
dataArray={plans.data}
renderRow={(item, i) => {
console.log('MS insideList : '+checkboxes && checkboxes.includes(item.id))
return(
<ListItem
key={item.id}
>
<Left>
<CheckBox
onPress={() => this.toggleCheckbox(item.id)}
checked={checkboxes && checkboxes.includes(item.id)}
/>
</Left>
<Text>
{item.name}
</Text>
</ListItem>)}}
/>
</View>
</Content>
</Container>
);
}
}
如何让复选框在列表中被选中?
为了其他用户的利益,这里是基于 Supriya 在下面的评论中的建议的代码修复:
解决方案
<FlatList
extraData={this.state}
data={plans.data}
keyExtractor={(item, index) => item.id}
renderItem={({item}) => {
const itemName = item.name;
return(
<ListItem>
<CheckBox
onPress={() => this.toggleCheckbox(item.id)}
checked={checkboxes && checkboxes.includes(item.id)}
/>
<Body>
<Text style={styles.planText}>
{item.name}
</Text>
</Body>
</ListItem>)}}
/>
版本:
设备:安卓
CRNA 应用程序与 Expo
github上也有类似的问题,https://github.com/GeekyAnts/NativeBase/issues/989有解决方案
它可以使用简单的代码,无需 listItem。 以下示例将复选框作为单选按钮处理,但可以轻松更改 onPress 函数以允许多项选择。
import React, { Component } from 'react';
import { View } from 'react-native';
import { CheckBox, Text } from 'native-base';
export default class SignupScreen extends Component {
state = {
one: false,
two: false,
three: false
};
render() {
return (
<View style={{ alignItems: 'flex-start' }}>
<View style={{ flexDirection: 'row' }}>
<CheckBox checked={this.state.one}
style={{ marginRight: 20 }}
onPress={this.onePressed.bind(this)}/>
<Text>One</Text>
</View>
<View style={{ flexDirection: 'row' }}>
<CheckBox checked={this.state.two}
style={{ marginRight: 20 }}
onPress={this.twoPressed.bind(this)}/>
<Text>Two</Text>
</View>
<View style={{ flexDirection: 'row' }}>
<CheckBox checked={this.state.three}
style={{ marginRight: 20 }}
onPress={this.threePressed.bind(this)}/>
<Text>Three</Text>
</View>
</View>
);
}
// checkbox functions
// if clicked button was set, only clear it
// otherwise, set it and clear the others
onePressed() {
if (this.state.one)
this.setState({ one: false });
else
this.setState({ one: true, two: false, three: false });
}
twoPressed() {
if (this.state.two)
this.setState({ two: false });
else
this.setState({ one: false, two: true, three: false });
}
threePressed() {
if (this.state.three)
this.setState({ three: false });
else
this.setState({ one: false, two: false, three: true });
}
}
我正在使用 Native Base for Web,并遇到了同样的问题。我的解决方案是将元素包装在 Pressable 中,然后使用 stopPropagation 事件禁用默认事件。
这是零食的链接 - https://snack.expo.dev/B472JfR6C