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

React Navigation页面挂载参数异常:旧参数留存后加载新参数

React Navigation 页面跳转参数异常问题复现与解决方案

我刚好复现了你遇到的这个React Native + React Navigation中的参数传递异常问题,下面是完整的复现细节、代码以及对应的解决办法:

复现场景

  • 包含两个页面:A(首页)和B(详情页)
  • A页有两个按钮,分别触发跳转到B页的操作,同时传递参数id:1和id:2
  • 在B页的render()和componentDidMount()生命周期方法中,都打印接收到的参数

异常现象

点击A页传递id:1的按钮时,B页的componentDidMount()和render()都正常输出id:1;但当从B页返回A页,再次点击传递id:2的按钮时,B页的componentDidMount()仍然输出id:1,只有render()能正确输出id:2。

完整复现代码

A页面(HomeScreen.js)

import React from 'react';
import { View, Button, StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native';

const HomeScreen = () => {
  const navigation = useNavigation();

  return (
    <View style={styles.container}>
      <Button
        title="跳转到B页(id:1)"
        onPress={() => navigation.navigate('Detail', { id: 1 })}
      />
      <Button
        title="跳转到B页(id:2)"
        onPress={() => navigation.navigate('Detail', { id: 2 })}
        style={styles.button}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 20,
  },
  button: {
    marginTop: 20,
  },
});

export default HomeScreen;

B页面(DetailScreen.js,类组件版本)

import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';

class DetailScreen extends Component {
  componentDidMount() {
    console.log('componentDidMount 接收的参数:', this.props.route.params?.id);
  }

  render() {
    const { id } = this.props.route.params || {};
    console.log('render 接收的参数:', id);
    return (
      <View style={styles.container}>
        <Text style={styles.text}>当前ID:{id}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 20,
  },
});

export default DetailScreen;

导航配置文件

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';
import DetailScreen from './DetailScreen';

const Stack = createStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Detail" component={DetailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;

问题根源

这个异常是由React Navigation的页面复用机制导致的:当你从A跳转到B再返回A时,B页面不会被卸载,而是保留在导航栈中。当你再次跳转至B页时,组件不会重新触发componentDidMount()(这个钩子只在组件首次挂载时执行),只会更新props。因此componentDidMount()中打印的还是第一次的参数,而render()会因为props更新重新渲染,所以能拿到最新的参数。

解决方案

如果需要在参数更新时执行对应逻辑,可以根据组件类型选择以下方案:

类组件修改方案

添加componentDidUpdate()钩子来监听参数变化:

componentDidUpdate(prevProps) {
  // 对比前后参数,若不同则执行更新逻辑
  if (prevProps.route.params?.id !== this.props.route.params?.id) {
    console.log('componentDidUpdate 接收的新参数:', this.props.route.params?.id);
    // 这里放置参数更新后需要执行的代码
  }
}

函数组件版本(推荐)

使用useEffect钩子监听route.params的变化,同时替代componentDidMount的逻辑:

import React, { useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useRoute } from '@react-navigation/native';

const DetailScreen = () => {
  const route = useRoute();
  const { id } = route.params || {};

  useEffect(() => {
    console.log('参数更新/首次加载:', id);
    // 这里的代码会在首次加载和参数变化时执行
  }, [id]); // 依赖项为id,当id变化时触发

  console.log('render 接收的参数:', id);
  return (
    <View style={styles.container}>
      <Text style={styles.text}>当前ID:{id}</Text>
    </View>
  );
};

// styles 保持不变
export default DetailScreen;

内容的提问来源于stack exchange,提问作者Whit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:59:33