开发者问题收集

在 React 中单击 FlatList 导航到另一个组件

2023-02-06
226

我使用 FlatList Component 屏幕中并排显示 ImageText 。我想单击任意行并打开一个新的 Component 类 [FoodItems] 并传递一个简单的字符串。

它说,“无法读取未定义的属性(读取‘navigate’)”。 我已安装所有必需的软件包。

npm install react-navigation

npm install @react-navigation/native

我不知道这里的 this.props 是什么?我没有从上一个屏幕发送道具。我只是从一些帖子中复制粘贴它。

Restaurants.js:

import { View, FlatList, Text, TouchableOpacity } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import withRouter from './withRouter';

class Restaurants extends Component {
  render() {
    if (!this.state.restaurantsSet) {
      this.setState({ restaurantsSet: true });
      this.settingRestaurants(this.props.location.state.station);
    }

    return (
      <View>
        <div className='header'></div>
        <FlatList
          ItemSeparatorComponent={this.FlatListItemSeparator}
          ListHeaderComponent={this.FlatListHeader} 
          style={{ flex: 1 }}
          data={this.state.restaurants}
          renderItem={({ item }) => 
            <TouchableOpacity 
              onPress={() => 
                this.props.navigation.navigate(
                  'FoodItems',
                  { message: 'my_message' }
                )
              }
            >
              <Row {...item} />
            </TouchableOpacity>
          }
        />
      </View>
    )
  }
}

export default withRouter(Restaurants);

withRouter.js:


import { useLocation, useParams, useNavigation } from 'react-router-dom'; 

const withRouter = WrappedComponent => props => {
  const location = useLocation();
  const params = useParams();
  const navigation = useNavigation();
  
  return (
    <WrappedComponent
      {...{props, params}}
      {...{ location, params,}}
      {...{navigation, params}}
    />
  );
};

export default withRouter;
1个回答

withRouter HOC 实现不正确。 useNavigation 钩子是 RRDv6.4 数据路由器专用钩子。重点是我。

This hook tells you everything you need to know about a page navigation to build pending navigation indicators and optimistic UI on data mutations. Things like:

  • Global loading indicators
  • Disabling forms while a mutation is happening
  • Adding busy indicators to submit buttons
  • Optimistically showing a new record while it's being created on the server
  • Optimistically showing the new state of a record while it's being updated

Important

This feature only works if using a data router , see Picking a Router

import { useNavigation } from "react-router-dom";

function SomeComponent() {
  const navigation = useNavigation();
  navigation.state;
  navigation.location;
  navigation.formData;
  navigation.formAction;
  navigation.formMethod;
}

useNavigation 钩子不用于发出任何命令式导航操作。为此,您应该导入并使用 useNavigate 钩子,因为这是返回 navigate 函数的钩子。

import { useLocation, useParams, useNavigate } from 'react-router-dom'; 

const withRouter = WrappedComponent => props => {
  const location = useLocation();
  const params = useParams();
  const navigate = useNavigate();
  
  return (
    <WrappedComponent
      {...props}
      {...{ location, params, navigate }}
    />
  );
};

export default withRouter;

React Class 组件中的访问 this.props.navigate 。不要忘记,您想要在路由状态中传递的数据是在 option 对象的 state 属性中传递的。

import { View, FlatList, Text, TouchableOpacity } from 'react-native';
import withRouter from './withRouter';

class Restaurants extends Component {
  ...

  componentDidMount() {
    if (!this.state.restaurantsSet) {
      this.setState({ restaurantsSet: true });
      this.settingRestaurants(this.props.location.state?.station);
    }
  }

  ...

  render() {
    return (
      <View>
        <div className='header'></div>
        <FlatList
          ItemSeparatorComponent={this.FlatListItemSeparator}
          ListHeaderComponent={this.FlatListHeader} 
          style={{ flex: 1 }}
          data={this.state.restaurants}
          renderItem={({ item }) => 
            <TouchableOpacity 
              onPress={() => 
                this.props.navigate(
                  'FoodItems',
                  { state: { message: 'my_message' }}
                );
              }
            >
              <Row {...item} />
            </TouchableOpacity>
          }
        />
      </View>
    )
  }
}

export default withRouter(Restaurants);
Drew Reese
2023-02-06