React Native训练管理APP数据不显示问题排查
搞定你的训练记录显示问题!
我帮你排查到了核心问题——你在render方法里直接调用了异步的数据库查询,这在React里是行不通的,异步操作不会立即返回结果,导致你的listItem根本没生成有效内容。下面是一步步的修复方案和修改后的完整代码:
核心问题拆解
mioDB.find()是异步函数,它的回调要等数据库查询完成才会执行,但render方法是同步执行的。当组件首次渲染时,listItem其实是undefined,自然看不到任何训练记录。
修复步骤与完整代码
1. 用组件状态管理数据
先给组件添加state来存储训练记录,这样数据更新时组件会自动触发重新渲染:
2. 在组件挂载后执行异步查询
用componentDidMount生命周期钩子,等组件挂载完成后再去查询数据库,拿到数据后更新state:
3. 遍历state生成列表项
在render里遍历state中的数据来生成Trainer组件,确保每次数据更新页面都会同步刷新:
4. 优化跳转方法(关键细节)
你的跳转函数大概率需要导航实例才能正常工作,记得把导航对象传进去(这里假设你用的是旧版react-native-navigator,如果是React Navigation请对应调整)
修改后的完整代码:
import React, {Component} from 'react'; import { Text, View, StyleSheet, Button, ScrollView, TouchableOpacity, Dimensions} from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; import Datastore from 'react-native-local-mongodb'; import Trainer from '../../components/Trainer/Trainer'; import startNewTraining from '../starts/startNewTraining/startNewTraining'; import startMainApp from '../starts/startMainApp/startMainApp'; let mioDB = new Datastore({filename:'mioDB',autoload:true}); class MainPage extends Component{ // 初始化状态存储训练记录 state = { trainings: [] }; // 组件挂载完成后执行异步数据库查询 componentDidMount() { mioDB.find({}, (err, docs) => { if (err) { console.error('查询训练记录失败:', err); return; } // 更新状态,触发组件重新渲染 this.setState({ trainings: docs }); }); } mainStartNewTrainer=()=>{ // 传递导航实例给跳转函数 startNewTraining(this.props.navigator); }; start=()=>{ // 传递导航实例给跳转函数 startMainApp(this.props.navigator); }; render(){ const addTraining=( <Icon size={Dimensions.get('window').height<600?40:60} name='add-circle-outline' color='black'/> ); // 遍历状态中的训练记录生成组件 const listItems = this.state.trainings.map((training)=>{ console.log(training); return ( <Trainer icon='A' key={training._id} onPress={this.start} style={{width:'100%',height:'100%'}} titleTrainer={training.trainingTitle} /> ); }); return( <View style={styles.container}> <Text style={styles.title}>Make your choice</Text> <View style={styles.containerTrainers}> <ScrollView horizontal={false} contentContainerStyle={styles.scrollContainer} bounces={false}> <Trainer onPress={this.mainStartNewTrainer} icon={addTraining} titleTrainer='Add new training'/> {listItems} </ScrollView> </View> </View> ); } } const styles=StyleSheet.create({ container:{ alignItems:'center', backgroundColor:'#8D0C42', height:'100%', justifyContent:'flex-start', width:'100%', }, containerTrainers:{ flexDirection:'row', width:'90%', }, scrollContainer:{ flexWrap:'wrap', width:'100%', }, title:{ color:'black', fontFamily:'Aclonica', fontSize:Dimensions.get('window').height<600?20:35, marginBottom:'3%', marginTop:'3%', maxWidth:'80%', textAlign:'justify', }, }); export default MainPage;
内容的提问来源于stack exchange,提问作者Federico Raimondi
相关产品推荐
相关产品推荐

