React Native自定义组件如何正确使用state及传值
卡牌计数应用State问题排查与修复方案
问题根因
- 父子组件传参名不匹配:App组件向
CardCount传递的属性名为useState,但CardCount组件解构接收的参数是currentCount,子组件无法获取到计数值,因此无法正常渲染计数结果。 - 缺失点击交互逻辑:当前
Card组件未绑定点击回调,点击卡牌时不会触发setCount方法更新状态,即使传参修复后数值也不会随点击变化。 - 遍历命名不规范:
cards.map((index) => ...)中传入的参数实际是遍历得到的卡牌对象,并非数组索引,命名错误容易引发后续逻辑bug。
修复后完整实现
入口App组件
import { View, StyleSheet } from 'react-native'; import { useState } from 'react'; import CardCount from './components/CardCount'; import Card from './components/Card'; export default function App() { const cards = [ { card: "A", count: -1 }, { card: "K", count: -1 }, { card: "Q", count: -1 }, { card: "J", count: -1 }, { card: 10, count: -1 }, { card: 9, count: 0 }, { card: 8, count: 0 }, { card: 7, count: 0 }, { card: 6, count: 1 }, { card: 5, count: 1 }, { card: 4, count: 1 }, { card: 3, count: 1 }, { card: 2, count: 1 }, ]; const [currentCount, setCount] = useState(0); // 处理卡牌点击计数更新 const handleCardPress = (addValue) => { // 用函数式更新避免连续点击状态不同步 setCount(prevCount => prevCount + addValue); }; return ( <View style={styles.app}> {/* 修正传参名,和子组件接收字段保持一致 */} <CardCount currentCount={currentCount}/> <View style={styles.cardsWrap}> {cards.map((cardItem, idx) =>( <Card key={idx} cardData={cardItem} onCardPress={() => handleCardPress(cardItem.count)} /> ))} </View> </View> ); } const styles = StyleSheet.create({ app: { flex: 1, paddingTop: 60, paddingHorizontal: 16 }, cardsWrap: { flexDirection: 'row', flexWrap: 'wrap', gap: 12, marginTop: 40 } });
计数展示组件CardCount
import { Text, StyleSheet } from 'react-native'; export const CardCount = ({currentCount}) => { return ( <Text style={styles.countText}>当前计数:{currentCount}</Text> ) } const styles = StyleSheet.create({ countText: { fontSize: 28, fontWeight: '700', textAlign: 'center' } }); export default CardCount;
卡牌组件Card
需要绑定点击事件,点击时触发父组件传入的回调:
import { TouchableOpacity, Text, StyleSheet } from 'react-native'; export const Card = ({cardData, onCardPress}) => { return ( <TouchableOpacity style={styles.cardItem} onPress={onCardPress}> <Text style={styles.cardLabel}>{cardData.card}</Text> </TouchableOpacity> ) } const styles = StyleSheet.create({ cardItem: { width: 52, height: 74, borderWidth: 1, borderColor: '#dcdcdc', borderRadius: 8, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' }, cardLabel: { fontSize: 22 } }); export default Card;
实现说明:点击卡牌时会自动把卡牌对应的计数值传给父组件的更新方法,A/K/Q/J/10点击减1,9/8/7点击数值不变,2-6点击加1,计数会实时同步到顶部展示区域。
内容的提问来源于stack exchange,提问作者ubermo
相关产品推荐
相关产品推荐

