React Native自定义Radio Button点击全选异常如何实现单选互斥
问题原因
当前实现用单个布尔类型的selected状态统一控制所有选项的选中态,3个选项共享同一个状态值,点击任意选项修改状态时,所有选项都会同步切换选中/未选中样式,无法实现互斥效果。
修复方案
将选中状态从布尔值改为存储当前选中项的唯一标识(可以是选项文本、索引或业务ID),渲染每个选项时,仅当选项标识和状态存储值一致时显示选中样式,点击选项时直接更新状态为当前选项的标识,自动覆盖之前的选中值实现互斥,同时将选中项的完整数据回传给父组件。
修正后的子组件(RadioButton)代码
import { useState } from 'react'; import { View, TouchableOpacity, Image, Text } from 'react-native'; // 请替换为你项目中Colors的实际引入路径 import { Colors } from '你的项目颜色配置路径'; const RadioButton = (props) => { // 初始值为null代表默认无选中项,后续存储当前选中项的text作为唯一标识 const [selectedValue, setSelectedValue] = useState(null); const { dataText, isSelected } = props; const handlePress = (item) => { setSelectedValue(item.text); // 将选中的完整项数据回传父组件 isSelected(item); }; return ( <> {dataText.map((item, index) => { const checked = selectedValue === item.text; return ( <View key={index} style={{ flexDirection: 'row', width: '50%', marginVertical: 10, alignItems: 'center' }} > <TouchableOpacity onPress={() => handlePress(item)}> {checked ? ( <Image source={require('../../assets/img/checkFullColor.png')} style={{ width: 20, height: 20, marginRight: 20, }} resizeMode="contain" /> ) : ( <View style={{ backgroundColor: Colors.accentDark, height: 20, width: 20, borderRadius: 50, marginRight: 20, }} /> )} </TouchableOpacity> <Text style={{ color: Colors.accentDark }}>{item.text}</Text> </View> ); })} </> ); }; export default RadioButton;
父组件调用调整
回调参数从原来的布尔值改为选中的项对象,可直接获取选中项的业务字段:
const radioData = [ { text: 'value A' }, { text: 'value B' }, { text: 'value C' }, ]; <RadioButton dataText={radioData} isSelected={(selectedItem) => { console.log('当前选中项:', selectedItem); // 输出格式为 {text: '对应选项值'} }} />
改动说明
- 合并了原来重复的
TouchableOpacity逻辑,减少冗余代码 - 给列表项添加了必填的
key属性,避免RN列表渲染警告 - 点击选项时直接更新选中值为当前项标识,其余选项因匹配不到选中值自动切为未选中状态,天然实现单选互斥
- 回传父组件的数据为完整选中项对象,可直接用于业务逻辑,无需额外转换
内容的提问来源于stack exchange,提问作者pratteek shaurya
相关产品推荐
相关产品推荐

