如何在 React Native 中将整个选择更改为单个选择?

Posted

技术标签:

【中文标题】如何在 React Native 中将整个选择更改为单个选择?【英文标题】:How do you change the entire selection to individual choices in React Native? 【发布时间】:2021-07-25 10:05:17 【问题描述】:

我们目前正在基于 React Native 进行开发。 我通过API文档通过GET请求接收数据, 我通过 MAP 方法创建了滚动视图。 所以现在我试图让选择成为可能, 但如果我选择一个,那就全都选好了。 如果我从我的代码中选择一个,如何让你一一选择?

import React,  useEffect, useState  from "react";
import  SvgCssUri  from "react-native-svg";
import  DeviceEventEmitter  from "react-native";
import 
  View,
  StyleSheet,
  TouchableHighlight,
  Text,
  ScrollView,
  Image,
 from "react-native";
import 
  widthPercentageToDP as wp,
  heightPercentageToDP as hp,
 from "react-native-responsive-screen";
import axios from "axios";
import BouncyCheckbox from "react-native-bouncy-checkbox";

const Select = ( navigation ) => 
  let bouncyCheckboxRef = null;
  const [bodyType, setBodyType] = useState([]);
  const [standardSelected, setStandardSelected] = useState(false);
  const [isSelected, setSelected] = useState(false);
  const bodyGetData = async () => 
    let body = [];
    try 
      let config = 
        method: "get",
        url:
          "http://everyweardev-env.eba-azpdvh2m.ap-northeast-2.elasticbeanstalk.com/api/v1/user/bodyType/male",
        headers: ,
      ;

      axios(config).then(function (response) 
        response.data.data.map((u) => 
          switch (u.bodyType) 
            case "standard":
              body.push( bodyType: "스탠다드", imgUrl: u.imgUrl, key: 1 );
              break;
            case "reverseTriangle":
              body.push( bodyType: "역삼각형", imgUrl: u.imgUrl, key: 2 );
              break;
            case "triangle":
              body.push( bodyType: "삼각형", imgUrl: u.imgUrl, key: 3 );
              break;
            case "circle":
              body.push( bodyType: "원형", imgUrl: u.imgUrl, key: 4 );
              break;
            case "hourglass":
              body.push( bodyType: "직사각형", imgUrl: u.imgUrl, key: 5 );
              break;
          
        );
        return setBodyType(body);
      );
     catch (err) 
      console.log(err);
    
  ;
  useEffect(() => 
    const unsubscribe = navigation.addListener("focus", () => 
      bodyGetData();
    );
    return unsubscribe;
  , [navigation]);

  const onClick = (e) => 
    console.log(e);
    bodyType.map((u) => 
      switch (u.bodyType) 
        case u.bodyType === "스탠다드":
          setSelected(!isSelected);
          console.log(isSelected);
          break;
        case "역삼각형":
          setSelected(!isSelected);
          break;
      
    );
  ;

  return (
    <View style=styles.container>
      <Text
        style= fontSize: wp("5.5%"), fontWeight: "bold", marginBottom: 21 
      >
        자신의 체형을 선택해 주세요
      </Text>
      <View style= flexDirection: "row", marginBottom: hp("10%") >
        <Text style= fontSize: wp("4.5%"), marginRight: wp("1%") >
          더 정확한 평가를 받으실 수 있습니다
        </Text>
        <Image
          source=require("../../images/smile.png")
          style= marginTop: hp("0.5%") 
        />
      </View>
      <ScrollView horizontal=true showsHorizontalScrollIndicator=true>
        bodyType.map((data) => (
          <>
            <TouchableHighlight
              style=styles.bodySelect
              value=data.bodyType
              onPress=onClick
              // onPress=() => bouncyCheckboxRef?.onPress()
            >
              <>
                <BouncyCheckbox
                  isChecked=!isSelected
                  ref=(ref) => (bouncyCheckboxRef = ref)
                  size=25
                  fillColor="black"
                  unfillColor="#FFFFFF"
                  iconStyle= borderColor: "white" 
                  textStyle= fontFamily: "JosefinSans-Regular" 
                  disableBuiltInState
                  onPress=onClick
                  style=
                    alignSelf: "flex-start",
                    marginLeft: wp("3%"),
                    marginTop: hp("2%"),
                  
                />
                <SvgCssUri
                  uri=data.imgUrl
                  
                  
                  marginTop="-5%"
                  key=data.key
                />
                <Text style=styles.bodytype>data.bodyType</Text>
              </>
            </TouchableHighlight>
          </>
        ))
      </ScrollView>
      <TouchableHighlight
        style=styles.button
        onPress=() => 
          navigation.navigate("얼굴형 정보 입력");
        
        underlayColor="gray"
      >
        <>
          <Text style=styles.text>선택 완료</Text>
        </>
      </TouchableHighlight>
    </View>
  );
;
const styles = StyleSheet.create(
  container: 
    justifyContent: "center",
    alignItems: "center",
    marginTop: hp("5%"),
  ,
  button: 
    justifyContent: "center",
    alignItems: "center",
    width: wp("70%"),
    height: hp("7%"),
    color: "white",
    backgroundColor: "black",
    borderRadius: 10,
    marginTop: hp("17%"),
  ,
  text: 
    color: "white",
    fontSize: wp("5.2%"),
    fontWeight: "bold",
  ,

  bodySelect: 
    marginLeft: 16,
    marginRight: 16,
    width: wp("70%"),
    height: hp("35%"),
    alignItems: "center",
    borderRadius: 30,
    backgroundColor: "#ffffff",
    shadowColor: "#000",
    shadowOffset: 
      width: 0,
      height: 3,
    ,
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5,
  ,
  bodytype: 
    marginTop: hp("3%"),
    fontWeight: "bold",
    fontSize: wp("8%"),
  ,
);
export default Select;

【问题讨论】:

【参考方案1】:

此示例说明如何选择个人选项。 执行以下步骤:

  //define state to save selected value inside it
  const [selected, setSelected] = React.useState();
  //handle item onPress
  const onPress = (item) => 
      setSelected(item);
  
  //check if item selected
  const isSelected = (item) => 
      return selected?.unique_id === item.unique_id;
  
  //and in render function
  <ScrollView>
     
        data.map((item, index) => 
            return(
              <ItemComponent
                onPress=() => setSelected(item)
                style=isSelected(item) ? selectedStyle : defaultStyle>
              
              </ItemComponent>
            )
        )
     
  </ScrollView>

全码试吃零食here

import * as React from 'react';
import  Text, View, StyleSheet, ScrollView, TouchableOpacity from 'react-native';


export default function App() 


  const [selected, setSelected] = React.useState();

  const data = [
    
      unique_id : 1,
      text : "item one"
    ,
    
      unique_id : 2,
      text : "item two"
    ,
    
      unique_id : 3,
      text : "item three"
    ,
    
      unique_id : 4,
      text : "item four"
    
  ];


  const onPress = (item) => 
      setSelected(item);
  

  const isSelected = (item) => 
      return selected?.unique_id === item.unique_id;
  


  return (
      <ScrollView>
        
          data.map((item, index) => 
            return(
              <TouchableOpacity
                key=item.unique_id
                onPress=() => 
                    setSelected(item);
               
               style=
                 padding : 25,
                 margin : 10,
                 backgroundColor : isSelected(item) ? "red" : "#eee"
                 
               >
               <Text>item.text</Text>

               </TouchableOpacity>
            )
          )
        

      </ScrollView>
  );



【讨论】:

以上是关于如何在 React Native 中将整个选择更改为单个选择?的主要内容,如果未能解决你的问题,请参考以下文章

在 React Native 中将状态从子组件传递到父组件

React Native:如何更改 onPress 事件的视图

React Native刷新屏幕/组件/更改状态

如何在 android 中设置 react native expo 选择器的样式

如何在 react-native 中将 JPG 图像转换为 PNG

如何在 React Native 中将字符串转换为数组