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

React中点击FlatList跳转至其他组件时遇navigate未定义问题

解决React Native中FlatList点击跳转时navigate未定义的错误

问题说明

在类组件Restaurants中使用FlatList展示内容,点击列表项时想跳转到FoodItems组件并传递字符串参数,却触发错误:Cannot read properties of undefined (reading 'navigate')。已安装react-navigation相关包,但对this.props的来源不清晰,代码复制自外部帖子,还自行编写了withRouter文件。

错误核心原因

  1. 路由库混淆:混用了Web端路由库react-router-dom和React Native专用路由库react-navigation,两者API完全不兼容,自行编写的withRouter传递的是Web路由的navigation对象,并非React Native所需的导航实例。
  2. 类组件导航注入错误:类组件需要通过React Navigation提供的高阶组件注入navigation props,而非自定义的withRouter。
  3. 代码细节问题:render方法中直接调用setState会触发无限重渲染;未初始化组件state;使用了React Native不支持的div标签;FlatList缺少必需的keyExtractor属性。

修复方案及完整代码

1. 安装必要依赖

如果使用React Navigation v5+,需补充安装兼容类组件的包:

npm install @react-navigation/compat @react-navigation/native-stack

2. 修正Restaurants组件代码

删除自定义的withRouter.js,改用React Navigation官方的withNavigation高阶组件:

import React, { Component } from 'react';
import { View, FlatList, Text, TouchableOpacity } from 'react-native';
import { withNavigation } from '@react-navigation/compat';

class Restaurants extends Component {
  constructor(props) {
    super(props);
    // 初始化组件state
    this.state = {
      restaurantsSet: false,
      restaurants: []
    };
    // 绑定方法避免this指向异常
    this.settingRestaurants = this.settingRestaurants.bind(this);
    this.FlatListItemSeparator = this.FlatListItemSeparator.bind(this);
    this.FlatListHeader = this.FlatListHeader.bind(this);
  }

  componentDidMount() {
    // 将数据初始化逻辑移到生命周期方法,避免render中调用setState
    if (!this.state.restaurantsSet) {
      this.setState({ restaurantsSet: true });
      // React Navigation v5+中参数通过route.params获取
      this.settingRestaurants(this.props.route.params?.station);
    }
  }

  settingRestaurants(station) {
    // 这里替换为你的餐厅数据获取逻辑(比如API请求)
    this.setState({
      restaurants: [
        { id: 1, name: '餐厅A' },
        { id: 2, name: '餐厅B' }
      ]
    });
  }

  FlatListItemSeparator() {
    return <View style={{ height: 1, backgroundColor: '#ccc' }} />;
  }

  FlatListHeader() {
    return (
      <View style={{ padding: 10, backgroundColor: '#f5f5f5' }}>
        <Text style={{ fontSize: 16, fontWeight: 'bold' }}>餐厅列表</Text>
      </View>
    );
  }

  render() {
    return (
      <View style={{ flex: 1 }}>
        {/* 替换React Native不支持的div为View */}
        <View style={{ height: 50, backgroundColor: '#2196F3' }}></View>
        <FlatList
          ItemSeparatorComponent={this.FlatListItemSeparator}
          ListHeaderComponent={this.FlatListHeader}
          style={{ flex: 1 }}
          data={this.state.restaurants}
          // FlatList必须添加keyExtractor
          keyExtractor={(item) => item.id.toString()}
          renderItem={({ item }) => (
            <TouchableOpacity
              onPress={() => {
                // 通过注入的navigation对象跳转并传参
                this.props.navigation.navigate('FoodItems', {
                  message: 'my_message'
                });
              }}
              style={{ padding: 15 }}
            >
              {/* 替换为你自己的Row组件,此处用Text示例 */}
              <Text>{item.name}</Text>
            </TouchableOpacity>
          )}
        />
      </View>
    );
  }
}

// 用withNavigation高阶组件注入navigation props
export default withNavigation(Restaurants);

3. 配置全局路由容器(示例App.js)

确保Restaurants和FoodItems都在React Navigation的栈路由中注册:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import Restaurants from './Restaurants';
import FoodItems from './FoodItems';

const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Restaurants">
        <Stack.Screen name="Restaurants" component={Restaurants} />
        <Stack.Screen name="FoodItems" component={FoodItems} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

4. FoodItems组件接收参数示例

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

function FoodItems({ route }) {
  // 从route.params中获取传递的参数
  const { message } = route.params;
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>收到的消息:{message}</Text>
    </View>
  );
}

export default FoodItems;

关键修复点总结

  • 彻底移除react-router-dom相关依赖和代码,统一使用React Navigation API
  • 类组件通过withNavigation高阶组件获取navigation实例
  • 避免在render方法中调用setState,将数据初始化逻辑移到componentDidMount
  • 修复React Native不兼容的HTML标签,补充FlatList必需属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 17:15:43