如何在React Native中修改并跟踪数组各元素的独立布尔状态
问题根因
你当前使用了全局的布尔状态pressed控制所有按钮的背景色,所有遍历生成的按钮都绑定了同一个状态变量,因此状态更新时所有按钮的样式都会同步变化。
方案1:状态提升到父组件,存储选中项的标识
该方案适合需要在父组件获取选中的vibe数据做后续逻辑处理的场景。
单选场景(仅允许同时选中一个按钮)
import { useState } from 'react'; import { View, Text, TouchableHighlight } from 'react-native'; function OnboardingVibes() { // 状态存储当前选中的vibe值,初始为null表示无选中项 const [selectedVibe, setSelectedVibe] = useState(null); return ( <View style={{marginTop: 40}}> <Text style={{fontSize: 22, color: '#FFF', marginBottom: 16}}>Vibes</Text> <View style={styles.buttonContainer}> {vibes.map((vibe) => { const isPressed = selectedVibe === vibe; return ( <TouchableHighlight onPress={() => setSelectedVibe(vibe)} style={{ backgroundColor: isPressed ? '#DDD' : '#4D2C5B', margin: 4, borderRadius: 4 }} key={`vibe-${vibe}`} > <Text style={styles.vibeButton}>{vibe}</Text> </TouchableHighlight> ) })} </View> </View> ); }
多选场景(允许同时选中多个按钮)
import { useState } from 'react'; import { View, Text, TouchableHighlight } from 'react-native'; function OnboardingVibes() { // 状态存储所有选中的vibe集合 const [selectedVibes, setSelectedVibes] = useState(new Set()); const toggleVibe = (vibe) => { const newSelected = new Set(selectedVibes); newSelected.has(vibe) ? newSelected.delete(vibe) : newSelected.add(vibe); setSelectedVibes(newSelected); } return ( <View style={{marginTop: 40}}> <Text style={{fontSize: 22, color: '#FFF', marginBottom: 16}}>Vibes</Text> <View style={styles.buttonContainer}> {vibes.map((vibe) => { const isPressed = selectedVibes.has(vibe); return ( <TouchableHighlight onPress={() => toggleVibe(vibe)} style={{ backgroundColor: isPressed ? '#DDD' : '#4D2C5B', margin: 4, borderRadius: 4 }} key={`vibe-${vibe}`} > <Text style={styles.vibeButton}>{vibe}</Text> </TouchableHighlight> ) })} </View> </View> ); }
方案2:封装独立子组件,内部维护自身状态
该方案适合不需要在父组件获取按钮选中状态,仅需要单个按钮自身切换样式的场景,代码更简洁解耦,各按钮状态互相独立不干扰。
import { useState } from 'react'; import { View, Text, TouchableHighlight } from 'react-native'; // 独立封装的Vibe按钮组件,自己管理选中状态 const VibeButton = ({vibe}) => { const [pressed, setPressed] = useState(false); return ( <TouchableHighlight onPress={() => setPressed(!pressed)} style={{ backgroundColor: pressed ? '#DDD' : '#4D2C5B', margin: 4, borderRadius: 4 }} > <Text style={styles.vibeButton}>{vibe}</Text> </TouchableHighlight> ) } // 父组件直接调用子组件即可 function OnboardingVibes() { return ( <View style={{marginTop: 40}}> <Text style={{fontSize: 22, color: '#FFF', marginBottom: 16}}>Vibes</Text> <View style={styles.buttonContainer}> {vibes.map((vibe) => ( <VibeButton vibe={vibe} key={`vibe-${vibe}`}/> ))} </View> </View> ); }
内容的提问来源于stack exchange,提问作者Oliver Darby
相关产品推荐
相关产品推荐

