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

React Native 页面间跳转时如何防止状态被重置?

问题原因

  • 你当前把消费列表expenseList存储在AddItem组件的内部状态中,每次从首页跳转进入AddItem页面时,React Navigation会创建新的AddItem组件实例,内部状态会重置为初始的空数组,旧的列表数据不会被保留。
  • 首页Home组件没有持久化存储列表数据,仅从路由参数临时读取列表,跳转至AddItem时也没有把已有列表传递过去,导致新增数据时直接覆盖了旧数据。

解决方法

核心思路是状态提升,把需要在多个页面共享的expenseList存储在父级页面Home的内部状态中,跳转AddItem时将已有列表传递过去,新增完成后再把更新后的列表同步回Home的状态。

具体修改步骤

  1. 改造Home组件,新增内部状态存储expenseList,跳转AddItem时传递已有列表和更新列表的回调函数
  2. 改造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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:15:02