You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 04:04:06