【问题标题】:how to set checked value in checkbox如何在复选框中设置选中值
【发布时间】:2019-06-01 13:51:58
【问题描述】:

在以下 React-native 代码中,我使用 native-base 复选框来考虑要考虑的函数是 _checkBox()_checkbox_check() 我使用了一个状态变量来保存值,无论它们是否处于状态cb{}

按下复选框时,我可以更改在_checkbox_check() 函数中使用console.log() 检查的值,但相同的值在checked={this.state.cb[data.id]} 处不起作用,这意味着对象cb 中的真假对应复选框的键在那里,但是当它为真时,复选框被选中, 虽然我已经检查过提供像 checked={true} 这样的静态值,但一切正常。

如果有错误或改进的机会,请提出建议 我的整个页面的代码如下

import React from "react";
import AsyncStorage from "@react-native-community/async-storage";
import {
   Text,
   View,
   ScrollView,
   Platform,
   Image,
   TouchableOpacity,
   ToastAndroid,
   StatusBar
   } from "react-native";

     import {
       Content,
       Container,
       Button,
       Icon,
       Header,
       Left,
       Right,
       Body,
       Title,
       Item,
       Card,
       CardItem,
       DatePicker,
       Label,
       Input,
       ListItem,
       CheckBox
     } from "native-base";

     import Network from "../../network/network";
     import LinearGradient from "react-native-linear-gradient";
     import * as constant from "../../Constants/Constant";
     const deviceHeight = constant.deviceHeight;
     const deviceWidth = constant.deviceWidth;
     import styles from "./Styles";
     import Styles from "./Styles";

     const icn = "../../Images/icons/blue/";
     const platform = Platform.OS;

     export default class SignInScreen extends React.Component {
       constructor(props) {
         super(props);
         this.state = {
           services: null,
           poolId: null,
           chosenDate: new Date(),
           choice: null,
           description: null,
           val: true,
           cb: {}
         };

         this.setDate = this.setDate.bind(this);
       }
       setDate(newDate) {
         this.setState({ chosenDate: newDate });
       }

       async componentWillMount() {
         await Network.Token_get("apk/getServiceList", async response => {
           if (response.status == true) {
             await this.setState({
               services: response.serviceData
             });
           }
         });
       }
       componentDidMount() {
         const { navigation } = this.props;
         const itemId = navigation.getParam("id");
         this.setState({
           poolId: itemId
         });
       }
       render() {
         return (
           <Container>
             <Header
               style={{
                 borderBottomWidth: 0,
                justifyContent: "center",
                 alignItem: "center"
               }}
             >
               <Left>
                 <Button
                      transparent
                   onPress={() => {
                     this.props.navigation.openDrawer();
                   }}
                 >
                   <Icon name="menu" />
                 </Button>
               </Left>
               <Body>
                 <Title style={styles.title}>Service Details</Title>
               </Body>
               <Right>
                 <Button transparent onPress={() => this._signOutAsync()}>
                   <Icon name="log-out" />
                 </Button>
               </Right>
             </Header>
             <Content contentContainerStyle={styles.content} bounces={false}>
               <ScrollView
                 contentContainerStyle={{
                   padding: 10,
                   alignItems: "flex-start",
                   justifyContent: "center",
                   backgroundColor: "#ffff",
                   shadowColor: "#1C0C59",
                   shadowOffsetWidth: 3,
                   shadowOffsetHeight: 3,
                   shadowOpacity: 0.1,
                   shadowRadius: 3,
                   elevation: 3,
                   borderRadius: 7,
                   bgColor: "#ffffff"
                 }}
               >
                 <View
                   style={{ alignItems: "flex-start", justifyContent: "flex-start" }}
                 >
                   {this._checkBoxes()}
                 </View>

                 <View style={{ flexDirection: "row" }}>
                   <View>
                     <Text style={{ top: 10 }}>
                       Schedule Date:
                       {/* {this.state.chosenDate.toString().substr(4, 12)} */}
                     </Text>
                   </View>
                   <View>
                     <DatePicker
                       defaultDate={new Date(2018, 4, 4)}
                       minimumDate={new Date(2018, 1, 1)}
                       maximumDate={new Date(2018, 12, 31)}
                       locale={"en"}
                       timeZoneOffsetInMinutes={undefined}
                       modalTransparent={false}
                       animationType={"fade"}
                       androidMode={"default"}
                       placeHolderText="Select Schedule Date"
                       // textStyle={{ color: "green" }}
                       placeHolderTextStyle={{ color: "#d3d3d3" }}
                       onDateChange={this.setDate}
                       disabled={false}
                     />
                   </View>
                 </View>

                 <Item floatingLabel style={{ marginTop: 20, marginBottom: 50 }}>
                  <Label>Description</Label>
                  <Input
                     multiline={true}
                     //  style={{height:200, textColor: "#000"}}
                     style={{ color: "#000", height: 100 }}
                     onChangeText={description => this.setState({ description })}
                   />
                 </Item>

                 <Button
                   rounded
                   primary
                   onPress={() => this._submit()}
                   style={{ paddingLeft: 18, alignSelf: "center" }}
                 >
                   <Text style={{ fontWeight: "600", color: "#000"          }}>Submit</Text>
                   <Icon name="send" />
                 </Button>
               </ScrollView>
             </Content>
           </Container>
         );
       }

       mapPools(poolList) {
         if (poolList) {
           return poolList.map(data => {
             return (
               <Card style={{ borderRadius: 7 }}>
                 <CardItem style={{ borderRadius: 7 }}>
                   <TouchableOpacity>
                     <View style={styles.View_inside_card}>
                       <View style={styles.Incard_icon_View}>
                         <Image
                           source={require(icn + "swimmingPool.png")}
                           style={styles.Incard_icon}
                         />
                       </View>
                       <View style={styles.Incard_Detail_View}>
                         <Text style={styles.Detail_name}>{data.pool_title}</Text>
                         <Text style={styles.Detail_name}>{data.address}</Text>
                       </View>
                     </View>
                   </TouchableOpacity>
                 </CardItem>
               </Card>
             );
           });
         }
       }

       _signOutAsync = async () => {
         var loginid = await AsyncStorage.getItem("@LoginID");
         payload = {
           loginId: loginid
         };
         await Network.Token_put("apk/logout", payload, async response => {
           ToastAndroid.show(response.message, ToastAndroid.SHORT);
           if (response.status === true) {
             await AsyncStorage.clear();
             this.props.navigation.navigate("Auth");
           }
         });
         // await AsyncStorage.clear();
         // this.props.navigation.navigate("Auth");
       };




       _checkBoxes = () => {
         if (this.state.services) {
           return this.state.services.map(data => {
             return (
               <ListItem noBorder>
                 <CheckBox
                   checked={this.state.cb[data.id]}
                   onPress={() => this._chkbox_check(data.id)}
                 />
                 <Text style={{ marginLeft: 20 }}>{data.services_title}</Text>
               </ListItem>
             );
           });
         }
       };

       _chkbox_check = param => {
         console.log(param, this.state.cb);

         if (this.state.cb.hasOwnProperty(param)) {
           var element = this.state.cb[param];
           console.log(element);
           this.state.cb[param] = !element;
           element = this.state.cb[param];
           console.log(element);
         } else {
           this.state.cb[param] = true;
         }
       };

       _submit = async sd => {
         var payload = {
           pool_id: this.state.poolId,
           request_schedule_dateTime: this.state.chosenDate,
           request_details: this.state.description,
           service_type_id: this.state.choice
         };
         var url = "apk/createPoolRequest";

         console.log("payload=>", payload);

         await Network.Token_post(url, payload, async response => {
           ToastAndroid.show(response.message, ToastAndroid.SHORT);
           if (response.status === true) {
             this.props.navigation.pop();
           }
         });
       };
     }

【问题讨论】:

    标签: javascript react-native native-base


    【解决方案1】:

    修改组件状态时应使用setState

    _chkbox_check = param => {
      if (this.state.cb.hasOwnProperty(param)) {
        var element = this.state.cb[param];
        this.setState({
          cb: {
            ...this.state.cb,
            [param]: !element,
          },
        });
      } else {
        this.setState({
          cb: {
            ...this.state.cb,
            [param]: true,
          },
        });
      }
    }
    

    根据文档,直接修改状态是一个很大的禁忌。有几个原因,但您遇到的问题是因为 render() 在调用 setState() 之后才会被触发。

    在上面的代码中setState 只会修改cb 状态,但是由于您不想完全覆盖cb(因为它存储了多个复选框的选中状态),所以您必须与spread operator...,并通过将 dynamic key 括在方括号 [] 中来访问它。

    这是一个去掉所有不相关代码的工作示例:

    import React from 'react';
    import { View } from 'react-native';
    import { ListItem, CheckBox } from 'native-base';
    
    export default class SignInScreen extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          cb: {}
        };
      }
    
      render() {
        return (
          <View>
            {this._checkBoxes()}
          </View>
        );
      }
    
      _checkBoxes = () => {
        const services = [
          { id: 'service1' },
          { id: 'service2' },
          { id: 'service3' },
        ];
        return services.map(data => {
          return (
            <ListItem noBorder>
              <CheckBox
                checked={this.state.cb[data.id]}
                onPress={() => this._chkbox_check(data.id)}
              />
            </ListItem>
          );
        });
      }
    
      _chkbox_check = param => {
        if (this.state.cb.hasOwnProperty(param)) {
          var element = this.state.cb[param];
          this.setState({
            cb: {
              ...this.state.cb,
              [param]: !element,
            },
          });
        } else {
          this.setState({
            cb: {
              ...this.state.cb,
              [param]: true,
            },
          });
        }
      }
    }
    

    如果您在setState 中省略带有...this.state.cb 的行,那么cb 将被新值完全覆盖。

    例如,假设您以:

    state.cb = { service1: true }
    

    然后拨打_chkbox_check('service2');,你会得到:

    state.cb = { service2: true }
    

    但是使用扩展运算符你会得到:

    state.cb = { service1: true, service2: true }
    

    旁注

    您的_chkbox_check 函数可以通过不检查状态中的属性来简化:

    _chkbox_check = param => {
      this.setState({
        cb: {
          ...this.state.cb,
          [param]: !this.state.cb[param],
        },
      });
    }
    

    这是因为JS使用truthy values,所以undefined会被解释为false。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 2013-11-09
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      相关资源
      最近更新 更多