React Native 页面间跳转时如何防止状态被重置?
问题原因
- 你当前把消费列表
expenseList存储在AddItem组件的内部状态中,每次从首页跳转进入AddItem页面时,React Navigation会创建新的AddItem组件实例,内部状态会重置为初始的空数组,旧的列表数据不会被保留。 - 首页
Home组件没有持久化存储列表数据,仅从路由参数临时读取列表,跳转至AddItem时也没有把已有列表传递过去,导致新增数据时直接覆盖了旧数据。
解决方法
核心思路是状态提升,把需要在多个页面共享的expenseList存储在父级页面Home的内部状态中,跳转AddItem时将已有列表传递过去,新增完成后再把更新后的列表同步回Home的状态。
具体修改步骤
- 改造
Home组件,新增内部状态存储expenseList,跳转AddItem时传递已有列表和更新列表的回调函数 - 改造
AddItem组件,初始化时读取路由传入的已有列表作为初始值,提交跳转前调用回调函数更新Home的列表数据
修改后的Home组件代码:
class Home extends Component { // 新增state存储全局的消费列表 state = { expenseList: [] } render() { const { expenseList } = this.state; return ( <View style={styles.container}> <Text style={styles.text}>Budget:</Text> <Button title="+" // 跳转时把当前已有列表传给AddItem onPress={() => this.props.navigation.navigate('AddItem', { existingList: expenseList, // 传入更新列表的回调函数 onListUpdate: (newList) => this.setState({ expenseList: newList }) })} /> <View> {expenseList.length === 0 && ( <TouchableOpacity onPress={() => this.props.navigation.navigate('AddItem', { existingList: expenseList, onListUpdate: (newList) => this.setState({ expenseList: newList }) })}> <Text>Create your first entry</Text> </TouchableOpacity> )} {expenseList.length > 0 && ( <FlatList style={styles.listContainer} data={expenseList} renderItem={(data) => <Text> title={data.item.name} </Text>} /> )} </View> </View> ); } }
修改后的AddItem组件代码:
class AddItem extends Component { state = { name: '', amount: '', // 初始化时从路由参数拿已有列表作为初始值 expenseList: this.props.route.params?.existingList || [], }; submitExpense = (name, amount) => { this.setState({ expenseList: [ ...this.state.expenseList, { key: Math.random(), name: name, amount: amount, }, ], }); }; deleteExpense = (key) => { this.setState({ expenseList: [ ...this.state.expenseList.filter((item) => item.key !== key), ], }); }; render() { const { onListUpdate } = this.props.route.params; return ( <View style={styles.container}> <TextInput style={styles.input} onChangeText={(name) => this.setState({ name })} value={this.state.name} placeholder="Name" keyboardType="default" /> {this.state.name === '' && ( <Text style={{ color: 'red', fontSize: 12, paddingLeft: 12 }}> Name is required </Text> )} <TextInput style={styles.input} onChangeText={(amount) => this.setState({ amount })} value={this.state.amount} placeholder="Amount" keyboardType="numeric" /> {this.state.amount === '' && ( <Text style={{ color: 'red', fontSize: 12, paddingLeft: 12 }}> Amount is required </Text> )} <Button title="Add" style={styles.btn} onPress={() => { if ( this.state.name.trim() === '' || this.state.amount.trim() === '' ) { alert('Please Enter the required values.'); } else { this.submitExpense( this.state.name, this.state.amount ); } }} /> <Button title="Go to Dashboard" style={styles.btn} onPress = {() => { // 先调用回调更新Home的列表,再跳转 onListUpdate(this.state.expenseList) this.props.navigation.navigate("Home"); }} /> <FlatList style={styles.listContainer} data={this.state.expenseList} renderItem={(data) => <Text> title={data.item.name} </Text>} /> </View> ); } }
如果后续应用复杂度提升,需要在更多页面共享消费列表数据,也可以改用Context API、Redux等全局状态管理方案实现数据持久化。
内容的提问来源于stack exchange,提问作者Menna Magdy
相关产品推荐
相关产品推荐

