簡體   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