【问题标题】:How to check individual item in FlatList with checkbox in react native?如何使用反应本机中的复选框检查 FlatList 中的单个项目?
【发布时间】:2020-05-13 10:31:25
【问题描述】:

我正在创建一个 React Native 应用程序,我使用此 react native checkbox 来检查 FlatList 中的单个项目。但是如果我检查一个项目,它会检查 FlatList 中的所有项目。我不能在数据数组中使用任何状态,比如this question answer 1. 有没有办法做到这一点或如何检查 FlatList 中的单个项目?

这是我试过的,

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  Image,
  Alert,
  ScrollView,
  FlatList,
} from 'react-native';
import {CheckBox} from 'react-native-elements';

export default class Test extends Component {

  constructor(props) {
    super(props);
    this.state = {
      calls: [
    {id:1,  name: "Mark Doe",   date:"12 jan", time:'11:14 am', image:"https://bootdey.com/img/Content/avatar/avatar7.png"},
    {id:2,  name: "Clark Man",  date:"12 jul", time:'15:58 am', image:"https://bootdey.com/img/Content/avatar/avatar6.png"} ,
    {id:3,  name: "Jaden Boor", date:"12 aug", time:'12:45 am', image:"https://bootdey.com/img/Content/avatar/avatar5.png"} ,
    {id:4,  name: "Srick Tree", date:"12 feb", time:'08:32 am', image:"https://bootdey.com/img/Content/avatar/avatar4.png"} ,
    {id:5,  name: "John Doe",   date:"12 oct", time:'07:45 am', image:"https://bootdey.com/img/Content/avatar/avatar3.png"} ,
    {id:6,  name: "John Doe",   date:"12 jan", time:'09:54 am', image:"https://bootdey.com/img/Content/avatar/avatar2.png"} ,
    {id:8,  name: "John Doe",   date:"12 jul", time:'11:22 am', image:"https://bootdey.com/img/Content/avatar/avatar1.png"} ,
    {id:9,  name: "John Doe",   date:"12 aug", time:'13:33 am', image:"https://bootdey.com/img/Content/avatar/avatar4.png"} ,
    {id:10, name: "John Doe",   date:"12 oct", time:'11:58 am', image:"https://bootdey.com/img/Content/avatar/avatar7.png"} ,
    {id:11, name: "John Doe",   date:"12 jan", time:'09:28 am', image:"https://bootdey.com/img/Content/avatar/avatar1.png"},
  ],
      checked: true,
    };
  }

  renderItem = ({item}) => {

    return (
      <TouchableOpacity>
        <View style={styles.row}>
          <Image source={{ uri: item.image }} style={styles.pic} />
          <View>
            <View style={styles.nameContainer}>
              <Text style={styles.nameTxt}>{item.name}</Text>
            </View>
            <View style={styles.end}>
              <Image style={[styles.icon, {marginLeft:15, marginRight:5, width:14, height:14}]} source={{uri:"https://img.icons8.com/small/14/000000/double-tick.png"}}/>
              <Text style={styles.time}>{item.date} {item.time}</Text>
            </View>
          </View>
          <CheckBox
            // iconRight
            title="SMS"
            checkedIcon="dot-circle-o"
            uncheckedIcon="circle-o"
            checked={this.state.checked}
            onPress={() => this.setState({checked: !this.state.checked})}
          />

        </View>
      </TouchableOpacity>
    );
  }

  render() {
    return(
      <View style={{ flex: 1 }} >
          <Text
          style={{
            fontSize: 26,
            color: '#0080ff',
            textAlign: 'center',
            marginBottom: 30,
            marginTop: 10,
          }}>
          Testing check box
        </Text>
        <FlatList 
          extraData={this.state}
          data={this.state.calls}
          keyExtractor = {(item) => {
            return item.id;
          }}
          renderItem={this.renderItem}/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    borderColor: '#dcdcdc',
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    padding: 10,
    justifyContent: 'space-between',

  },
  pic: {
    borderRadius: 25,
    width: 50,
    height: 50,
  },
  nameContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    // width: 270,
  },
  nameTxt: {
    marginLeft: 15,
    fontWeight: '600',
    color: '#222',
    fontSize: 15,

  },
  mblTxt: {
    fontWeight: '200',
    color: '#777',
    fontSize: 13,
  },
  end: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  time: {
    fontWeight: '400',
    color: '#666',
    fontSize: 12,

  },
  icon:{
    height: 28,
    width: 28, 
  }
});

【问题讨论】:

  • state.calls 中的每个 item 应该有一个 checked 属性,然后是 checked={item.checked}
  • 更新和测试

标签: reactjs react-native react-native-elements


【解决方案1】:

github 仓库:https://github.com/denistsoi/so-61772299

state.calls 中,每个项目都应该有一个checked 属性,然后复选框应该有一个属性checked={item.checked}

您需要更改 onPress 以更改通话状态

  isChecked = (itemId) => {
    const isThere = this.state.ids.includes(itemId);
    return isThere;
  };

  toggleChecked = (itemId) => {
    const ids = [...this.state.ids, itemId];

    if (this.isChecked(itemId)) {
      this.setState({
        ...this.state,
        ids: this.state.ids.filter((id) => id !== itemId),
      });
    } else {
      this.setState({
        ...this.state,
        ids,
      });
    }
  };
<CheckBox
  // iconRight
  title="SMS"
  checkedIcon="dot-circle-o"
  uncheckedIcon="circle-o"
  checked={this.isChecked(item.id)}
  onPress={() => this.toggleChecked(item.id)}
/>

组件

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  Image,
  Alert,
  ScrollView,
  FlatList,
} from 'react-native';
import { CheckBox } from 'react-native-elements';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      calls: [
      {id:1,  name: "Mark Doe",   date:"12 jan", time:'11:14 am', image:"https://bootdey.com/img/Content/avatar/avatar7.png"},
      {id:2,  name: "Clark Man",  date:"12 jul", time:'15:58 am', image:"https://bootdey.com/img/Content/avatar/avatar6.png"} ,
      {id:3,  name: "Jaden Boor", date:"12 aug", time:'12:45 am', image:"https://bootdey.com/img/Content/avatar/avatar5.png"} ,
      {id:4,  name: "Srick Tree", date:"12 feb", time:'08:32 am', image:"https://bootdey.com/img/Content/avatar/avatar4.png"} ,
      {id:5,  name: "John Doe",   date:"12 oct", time:'07:45 am', image:"https://bootdey.com/img/Content/avatar/avatar3.png"} ,
      {id:6,  name: "John Doe",   date:"12 jan", time:'09:54 am', image:"https://bootdey.com/img/Content/avatar/avatar2.png"} ,
      {id:8,  name: "John Doe",   date:"12 jul", time:'11:22 am', image:"https://bootdey.com/img/Content/avatar/avatar1.png"} ,
      {id:9,  name: "John Doe",   date:"12 aug", time:'13:33 am', image:"https://bootdey.com/img/Content/avatar/avatar4.png"} ,
      {id:10, name: "John Doe",   date:"12 oct", time:'11:58 am', image:"https://bootdey.com/img/Content/avatar/avatar7.png"} ,
      {id:11, name: "John Doe",   date:"12 jan", time:'09:28 am', image:"https://bootdey.com/img/Content/avatar/avatar1.png"},
      ],
      ids: [],
    };
  }

  isChecked = (itemId) => {
    const isThere = this.state.ids.includes(itemId);
    return isThere;
  };

  toggleChecked = (itemId) => {
    const ids = [...this.state.ids, itemId];

    if (this.isChecked(itemId)) {
      this.setState({
        ...this.state,
        ids: this.state.ids.filter((id) => id !== itemId),
      });
    } else {
      this.setState({
        ...this.state,
        ids,
      });
    }
  };

  renderItem = ({ item }) => {
    return (
      <TouchableOpacity>
        <View style={styles.row}>
          <Image source={{ uri: item.image }} style={styles.pic} />
          <View>
            <View style={styles.nameContainer}>
              <Text style={styles.nameTxt}>{item.name}</Text>
            </View>
            <View style={styles.end}>
              <Image
                style={[
                  styles.icon,
                  { marginLeft: 15, marginRight: 5, width: 14, height: 14 },
                ]}
                source={{
                  uri: 'https://img.icons8.com/small/14/000000/double-tick.png',
                }}
              />
              <Text style={styles.time}>
                {item.date} {item.time}
              </Text>
            </View>
          </View>
          <CheckBox
            // iconRight
            title="SMS"
            checkedIcon="dot-circle-o"
            uncheckedIcon="circle-o"
            checked={this.isChecked(item.id)}
            onPress={() => this.toggleChecked(item.id)}
          />
        </View>
      </TouchableOpacity>
    );
  };

  render() {
    return (
      <View style={{ flex: 1 }}>
        <Text
          style={{
            fontSize: 26,
            color: '#0080ff',
            textAlign: 'center',
            marginBottom: 30,
            marginTop: 10,
          }}
        >
          Testing check box
        </Text>
        <FlatList
          extraData={this.state}
          data={this.state.calls}
          keyExtractor={(item) => {
            return `${item.id}`;
          }}
          renderItem={this.renderItem}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    borderColor: '#dcdcdc',
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    padding: 10,
    justifyContent: 'space-between',
  },
  pic: {
    borderRadius: 25,
    width: 50,
    height: 50,
  },
  nameContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    // width: 270,
  },
  nameTxt: {
    marginLeft: 15,
    fontWeight: '600',
    color: '#222',
    fontSize: 15,
  },
  mblTxt: {
    fontWeight: '200',
    color: '#777',
    fontSize: 13,
  },
  end: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  time: {
    fontWeight: '400',
    color: '#666',
    fontSize: 12,
  },
  icon: {
    height: 28,
    width: 28,
  },
});

export default App;

【讨论】:

  • 在我的“调用”数组中不使用任何状态有什么办法吗?
  • 如果你支持我可以编辑这个 - 但基本上你有一个值来存储你选择的索引
  • 我可以投票。问题是我正在使用 API 获取数组的值。没有任何状态,例如已检查的属性。这就是为什么我希望以另一种方式做到这一点。
  • 我试过你的第一种方法。但它给了我一个错误。 “找不到变量:状态”
  • 我也试过你的第二种方法。它一次只能检查一项。我需要检查多个项目。
猜你喜欢
  • 2020-08-13
  • 1970-01-01
  • 2019-05-20
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多