React Native中如何在类组件间传递单选按钮数据并生成随机FlatList?
解决方案:React Native类组件间数据传递与随机列表生成
嘿,很高兴能帮你搞定这个问题!你当前的核心需求是在两个类组件之间传递单选按钮的选中值,并根据这些值筛选、随机生成练习列表。下面是一步步的具体方案:
1. 导航时传递选中参数
在Auswahl组件中,点击按钮跳转到UebungenAnzeigen时,通过React Navigation的navigate方法把选中的value1(练习水平)和value2(练习焦点)作为参数传递过去:
// 修改Auswahl组件中的Button onPress逻辑 <Button style={{margin:10, padding:10}} title="Erstelle meinen Plan" onPress={() => this.props.navigation.navigate('UebungenAnzeigen', { level: this.state.value1, focus: this.state.value2 }) } />
2. 接收参数并处理数据逻辑
在UebungenAnzeigen组件中,我们需要完成:接收导航参数、根据分类筛选数据、随机选取部分条目这几个步骤。
首先,定义完整的分类练习数据源(你可以根据实际需求扩展内容):
// 在UebungenAnzeigen组件外部定义全局数据源 const fullUebungenData = { first: { // Anfgänger(新手) first: [ // Dehnung(拉伸) { "name": "Herabschauender Hund", "kategorie":"Basic", "nummer" : "0", "erklaerung": "Steißbein zur Decke | Rücken gerade | Kopf in Verlängerung der Wirbelsäule", "photo": "", "dauer": 30 }, { "name": "Katze", "nummer" : "2", "erklaerung": "Steißbein zur Decke | Rücken gerade | Kopf in Verlängerung der Wirbelsäule", "photo": "", "dauer": 20 }, { "name": "Berggipfel", "nummer" : "3", "erklaerung": "Füße hüftbreit | Rücken gerade | Arme nach oben", "photo": "", "dauer": 25 } ], second: [ // Hüftöfner(开髋) { "name": "Hockstellung", "nummer" : "4", "erklaerung": "Knie über Zehen | Rücken gerade | Arme voraus", "photo": "", "dauer": 30 }, { "name": "Pflanze", "nummer" : "5", "erklaerung": "Ein Bein vorne | Knie 90 Grad | Rücken gerade", "photo": "", "dauer": 25 } ], third: [ // Energie(活力) { "name": "Sonnengruß A", "nummer" : "6", "erklaerung": "Fließende Bewegung von Berggipfel zu Herabschauendem Hund", "photo": "", "dauer": 40 }, { "name": "Kobra", "nummer" : "7", "erklaerung": "Bauch auf Boden | Arme drücken | Brust heben", "photo": "", "dauer": 20 } ] }, second: { // Geübt(熟练) first: [ { "name": "Vorwärtsbeugen", "nummer" : "8", "erklaerung": "Beine gerade | Rücken lang | Arme zum Boden", "photo": "", "dauer": 35 } ], // 补充其他焦点分类数据... }, third: { // Eingeschränkt(受限) first: [ { "name": "Sitzende Vorwärtsbeugen", "nummer" : "9", "erklaerung": "Sitzen | Beine gerade | Oberkörper nach vorne", "photo": "", "dauer": 30 } ], // 补充其他焦点分类数据... } };
然后修改UebungenAnzeigen组件的逻辑,在componentDidMount中处理数据:
class UebungenAnzeigen extends React.Component { constructor(props){ super(props); this.state = { data: [] // 初始化为空数组 } } componentDidMount() { // 获取导航传递的选中参数 const { level, focus } = this.props.route.params; // 获取对应分类的练习数据(无匹配项时返回空数组) const filteredData = fullUebungenData[level]?.[focus] || []; // 随机选取3个条目(可根据需求调整数量) const randomCount = 3; const randomData = []; const availableIndices = [...Array(filteredData.length).keys()]; while (randomData.length < randomCount && availableIndices.length > 0) { const randomIndex = Math.floor(Math.random() * availableIndices.length); const selectedIndex = availableIndices.splice(randomIndex, 1)[0]; randomData.push(filteredData[selectedIndex]); } // 更新state,渲染随机列表 this.setState({ data: randomData }); } render() { return ( <View> <View style={stylesUebungAnzeigen.container2}> <FlatList style={{flex:1}} data={this.state.data} renderItem={({ item }) => <Item item={item}/>} keyExtractor={(item) => item.nummer} // 用唯一的nummer作为列表项key /> </View> </View> ); } }
3. 修复Item组件的Hook使用问题
你原来的Item组件在类组件的render方法里使用了useState,这不符合Hook的使用规则(Hook只能在函数组件或自定义Hook中使用)。我们把Item改成独立的函数组件:
// 定义在UebungenAnzeigen组件外部 const Item = ({ item }) => { const [shouldShow, setShouldShow] = useState(true); return ( <View style={styles.container}> {/* 详情面板 */} {!shouldShow && ( <View style={stylesUebungAnzeigen.uebung}> <Text>Details</Text> <Text style={{marginTop: 20 }}>{item.name}</Text> <Text style={{marginTop: 10 }}>{item.erklaerung}</Text> <TouchableOpacity style={{marginTop: 100, color:'green'}} onPress={() => setShouldShow(!shouldShow)} > <Text>Zurück zur Übersicht</Text> </TouchableOpacity> </View> )} {/* 列表项面板 */} {shouldShow && ( <View style={stylesUebungAnzeigen.listItem}> <Image source={item.photo ? {uri: item.photo} : require('./default-image.png')} // 处理空图片场景 style={{width:90, height:60, borderRadius:10}} /> <View style={{alignItems:"center",flex:1}}> <Text style={{fontWeight:"bold"}}>{item.name}</Text> <Text>{item.dauer} Sekunden</Text> </View> <TouchableOpacity onPress={() => setShouldShow(!shouldShow)} style={{height:50,width:50, justifyContent:"center", alignItems:"center"} } > <Text style={{color:"green", fontWeight:"bold"}}>Hilfestellung?</Text> </TouchableOpacity> </View> )} </View> ); };
其他可选方案
如果你的App后续会变得更复杂,需要在多个组件间共享状态,还可以考虑:
- React Context API:创建全局上下文来管理选中的分类参数,所有需要的组件都可以直接访问
- Redux/MobX:适合大型应用的状态管理库,统一管理应用状态
不过对于当前的场景,导航传参是最简单、最直接的解决方案。
内容的提问来源于stack exchange,提问作者user12315151
相关产品推荐
相关产品推荐

