繁体   English   中英

单选按钮在本机反应中无法正常工作

[英]Radio button not working properly in react native

我正在制作本机反应的自定义单选按钮。

父组件

const radioData = [
  { text: 'value A' },
  { text: 'value B' },
  { text: 'value C' },
];

<RadioButton
  dataText={radioData}
  isSelected={(selected) => {
    console.log('<><>', selected);
  }}
/>

子组件

const RadioButton= (props) => {
 const [selected, setSelected] = useState(false);
 let { dataText, isSelected } = props;
 return (
  <>
   {dataText.map((item) => {
    return (
     <View
      style={{
       flexDirection: 'row',
       width: '50%',
       marginVertical: 10,
      }}
     >
      {selected ? (
       <TouchableOpacity
        onPress={() => {
          if (selected) {
            setSelected(false);
            isSelected(false);
           } else {
            setSelected(true);
            isSelected(true);
           }
        }}
       >
        <Image
         source={require('../../assets/img/checkFullColor.png')}
         style={{
          width: 20,
          height: 20,
          marginRight: 20,
         }}
         resizeMode={'contain'}
        />
       </TouchableOpacity>
      ) : (
       <TouchableOpacity
        onPress={() => {
          if (selected) {
            setSelected(false);
            isSelected(false);
           } else {
            setSelected(true);
            isSelected(true);
           }
        }}
       >
        <View
         style={{
          backgroundColor: Colors.accentDark,
          height: 20,
          width: 20,
          borderRadius: 50,
          marginRight: 20,
         }}
        />
       </TouchableOpacity>
      )}
      <Text style={{ color: Colors.accentDark }}>{item.text}</Text>
     </View>
    );
   })}
  </>
 );
};

问题是即使我单击任何一个 RadioButton,然后所有 3 个都被选中或取消选中。

我想要一个功能,我单击其中一个然后其他被取消选择,并且选定的值在父组件中更新。

您的RadioButton组件应该只渲染一个单选按钮,而不是一次渲染所有单选按钮。 所以你应该在父组件中映射radioData 现在, RadioButton组件中映射的每个单选按钮的selected状态都是相同的。

父组件的相关部分:

const radioData = [
  { text: 'value A' },
  { text: 'value B' },
  { text: 'value C' },
];

return render (
    <View>
        {radioData.map((item) => {                    <- map here
            <RadioButton dataText={item.text} />
        })
    </View>
);

并删除RadioButton组件中的映射。

/...
return (
    <>
        // {dataText.map((item) => {                  <- remove this
/...

如果你想要一个渲染多个单选按钮的组件,请将映射保留在RadioButton组件中,但还要为每个单选按钮设置状态。 我强烈建议您不要这样做,并将RadioComponent限制为单选按钮的一个实例。

我认为您的问题是您尝试使用一个布尔值来跟踪当前选择的 RadioButton 是否存在。 如果您想使用布尔值来跟踪,那么每个 radioData 项都需要一个布尔值,并且每次进行选择时,都需要更新所有其他布尔值。 一种更简单的方法是只跟踪选定的索引,并比较索引:(这是一个小吃演示

import React,{
  useState,
  useEffect
} from 'react';
import {
  View,
  Image,
  TouchableOpacity,
 // FlatList,
  Text,
  StyleSheet
} from 'react-native';

export default function RadioButton({onSelection,options, defaultSelection}){
  // instead of giving each list item an isSelected prop just keep
  // track of the selected index
  const [selectedIndex, setSelectedIndex] = useState(defaultSelection || 0)
  // its much cleaner to use an effect to allow subscriptions to changes
  useEffect(()=>{
    onSelection(selectedIndex,options[selectedIndex])
  },[selectedIndex])
  return (
    <View style={styles.container}>
      {
        options.map((item,index)=>{
          return (
            <TouchableOpacity style={styles.rowItem} onPress={()=>setSelectedIndex(index)}>
              {index == selectedIndex &&
                <Image
                  source={require('../../assets/snack-icon.png')}
                  style={{
                  width: 20,
                  height: 20,
                  marginRight: 20,
                  }}
                  resizeMode={'contain'}
                />
              }
              <Text>{item.text}</Text>
            </TouchableOpacity>
          )
        })
      }
    </View>
  )
}
const styles = StyleSheet.create({
  container:{
    width:'100%',
    height:'20%',
    flexDirection: 'row',
    flexWrap:'wrap',
    justifyContent:'space-between',
    alignItems:'center'
  },
  row:{

  },
  rowItem:{
    // width: '50%',
    paddingVertical:10,
    marginVertical: 10,
  }
})

和父组件:

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import RadioButton from './src/components/RadioButton'


export default function App() {
  const radioData = [
    { text: 'value A' },
    { text: 'value B' },
    { text: 'value C' },
  ];
  return (
    <View style={styles.container}>
      <RadioButton
        options={radioData}
        onSelection={(index,value) => {
          console.log('<><>', value);
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM