【问题标题】:Handle multiple checkboxes in expo react native处理博览会中的多个复选框反应原生
【发布时间】:2021-03-20 03:48:11
【问题描述】:

我希望能够在我的 expo react 本机应用程序中添加多个复选框。我在下面提供相关代码。我的班级中有一个数组,其中包含有关复选框的详细信息,它有一个 id,必须旁边的文本以及检查复选框是否被选中。


我的代码


class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0,
            inputTxt: "",
            checks: [
                {id: 1, txt: "first check", isChecked: false },
                {id: 2, txt: "second check", isChecked: false }
            ]
        };
    }
    render() {
        return (
            <View style={styles.container}>
                <Text style={styles.text}>Details Screen</Text>
                <View>
                    <View style={styles.checkboxContainer}>
                        <CheckBox/>
                         {/* Add all the checkboxes from my this.state.checks array here */}
                        <Text style={styles.label}>Do you like React Native?</Text>
                    </View>
                </View>
              [...]
            </View>
        );
    }
}

【问题讨论】:

    标签: javascript reactjs react-native checkbox expo


    【解决方案1】:

    以下是您可以非常轻松地实现它的方法。

    我在这里使用了功能组件而不是基于类的组件,但底层逻辑保持不变:

    最终输出:

    示例 1:完整源代码(使用功能组件和 Hook):

    import React, { useState, useEffect } from 'react';
    import {
      Text,
      View,
      StyleSheet,
      FlatList,
      CheckBox,
      Button,
      Modal,
    } from 'react-native';
    import Constants from 'expo-constants';
    
    // You can import from local files
    import AssetExample from './components/AssetExample';
    
    // or any pure javascript modules available in npm
    import { Card } from 'react-native-paper';
    
    const data = [
      { id: 1, txt: 'first check', isChecked: false },
      { id: 2, txt: 'second check', isChecked: false },
      { id: 3, txt: 'third check', isChecked: false },
      { id: 4, txt: 'fourth check', isChecked: false },
      { id: 5, txt: 'fifth check', isChecked: false },
      { id: 6, txt: 'sixth check', isChecked: false },
      { id: 7, txt: 'seventh check', isChecked: false },
    ];
    
    export default App = () => {
      const [products, setProducts] = useState(data);
    
      const handleChange = (id) => {
        let temp = products.map((product) => {
          if (id === product.id) {
            return { ...product, isChecked: !product.isChecked };
          }
          return product;
        });
        setProducts(temp);
      };
    
      let selected = products.filter((product) => product.isChecked);
    
      const renderFlatList = (renderData) => {
        return (
          <FlatList
            data={renderData}
            renderItem={({ item }) => (
              <Card style={{ margin: 5 }}>
                <View style={styles.card}>
                  <View
                    style={{
                      flexDirection: 'row',
                      flex: 1,
                      justifyContent: 'space-between',
                    }}>
                    <CheckBox
                      value={item.isChecked}
                      onChange={() => {
                        handleChange(item.id);
                      }}
                    />
                    <Text>{item.txt}</Text>
                  </View>
                </View>
              </Card>
            )}
          />
        );
      };
    
      return (
        <View style={styles.container}>
          <View style={{ flex: 1 }}>{renderFlatList(products)}</View>
          <Text style={styles.text}>Selected </Text>
          <View style={{ flex: 1 }}>{renderFlatList(selected)}</View>
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
        padding: 8,
      },
    
      card: {
        padding: 10,
        margin: 5,
        flexDirection: 'row',
        justifyContent: 'space-between',
      },
      modalView: {
        margin: 20,
        backgroundColor: 'white',
        borderRadius: 20,
        padding: 5,
        justifyContent: 'space-between',
        alignItems: 'center',
        elevation: 5,
      },
      text: {
        textAlign: 'center',
        fontWeight: 'bold',
      },
    });
    
    

    您可以在此处使用已完成的工作代码:Expo Snack

    示例 2:完整源代码(使用基于类的组件):

    import React, { useState, useEffect, Component } from 'react';
    import {
      Text,
      View,
      StyleSheet,
      FlatList,
      CheckBox,
      Button,
      Modal,
    } from 'react-native';
    import Constants from 'expo-constants';
    
    // You can import from local files
    import AssetExample from './components/AssetExample';
    
    // or any pure javascript modules available in npm
    import { Card } from 'react-native-paper';
    
    const data = [
      { id: 1, txt: 'first check', isChecked: false },
      { id: 2, txt: 'second check', isChecked: false },
      { id: 3, txt: 'third check', isChecked: false },
      { id: 4, txt: 'fourth check', isChecked: false },
      { id: 5, txt: 'fifth check', isChecked: false },
      { id: 6, txt: 'sixth check', isChecked: false },
      { id: 7, txt: 'seventh check', isChecked: false },
    ];
    
    export default class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          products: data,
        };
      }
    
      handleChange = (id) => {
        let temp = this.state.products.map((product) => {
          if (id === product.id) {
            return { ...product, isChecked: !product.isChecked };
          }
          return product;
        });
        this.setState({
          products: temp,
        });
      };
    
      renderFlatList = (renderData) => {
        return (
          <FlatList
            data={renderData}
            renderItem={({ item }) => (
              <Card style={{ margin: 5 }}>
                <View style={styles.card}>
                  <View
                    style={{
                      flexDirection: 'row',
                      flex: 1,
                      justifyContent: 'space-between',
                    }}>
                    <CheckBox
                      value={item.isChecked}
                      onChange={() => {
                        this.handleChange(item.id);
                      }}
                    />
                    <Text>{item.txt}</Text>
                  </View>
                </View>
              </Card>
            )}
          />
        );
      };
    
      render() {
        let selected = this.state.products?.filter((product) => product.isChecked);
        return (
          <View style={styles.container}>
            <View style={{ flex: 1 }}>
              {this.renderFlatList(this.state.products)}
            </View>
            <Text style={styles.text}>Selected </Text>
            <View style={{ flex: 1 }}>{this.renderFlatList(selected)}</View>
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
        padding: 8,
      },
    
      card: {
        padding: 10,
        margin: 5,
        flexDirection: 'row',
        justifyContent: 'space-between',
      },
      modalView: {
        margin: 20,
        backgroundColor: 'white',
        borderRadius: 20,
        padding: 5,
        justifyContent: 'space-between',
        alignItems: 'center',
        elevation: 5,
      },
      text: {
        textAlign: 'center',
        fontWeight: 'bold',
      },
    });
    

    您可以在此处使用已完成的工作代码:Expo Snack

    【讨论】:

    • 谢谢,之前没有看到这么详细的回答。
    • 很高兴它有帮助,编码愉快:)
    • 您能否更新您的答案以显示与类一起使用的解决方案,因为在类中使用 useSate 挂钩有点棘手,未来的用户可能也希望看到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    相关资源
    最近更新 更多