Native-Base - 列表内的复选框未被选中

问题描述 投票:0回答:3

我已经从 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

android react-native native-base
3个回答
2
投票

github上也有类似的问题,https://github.com/GeekyAnts/NativeBase/issues/989有解决方案


1
投票

它可以使用简单的代码,无需 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 });
  }
}

0
投票

我正在使用 Native Base for Web,并遇到了同样的问题。我的解决方案是将元素包装在 Pressable 中,然后使用 stopPropagation 事件禁用默认事件。

这是零食的链接 - https://snack.expo.dev/B472JfR6C

© www.soinside.com 2019 - 2024. All rights reserved.