【问题标题】:React Native - Navigate to screen - Invalid hook callReact Native - 导航到屏幕 - 无效的挂钩调用
【发布时间】:2020-06-27 06:23:43
【问题描述】:

App.js:

import React, { Component } from 'react';
import {View,Text} from 'react-native';
import { createDrawerNavigator } from 'react-navigation-drawer';
import {createAppContainer} from 'react-navigation';

import Epics from './screens/tmp';
import Pager from './screens/Pager';

const DrawerNavigator = createDrawerNavigator({
 Home: {screen: Epics},
 Page: {screen: Pager}
},{initialRouteName: 'Home'});

const Stack = createAppContainer(DrawerNavigator);

export default class App extends Component {
  render() {
    return <Stack />;
  }
}

尝试通过自定义组件导航到屏幕:

import { ActivityIndicator, Image, StyleSheet, View, TouchableHighlight } from 'react-native';
import PropTypes from 'prop-types';
import React from 'react';
import { useNavigation } from 'react-navigation-hooks';

import AuthorRow from './AuthorRow';

export default class Card extends React.Component {

  static propTypes = {
    fullname: PropTypes.string.isRequired,
    image: Image.propTypes.source.isRequired,
    linkText: PropTypes.string.isRequired,
    onPressLinkText: PropTypes.func.isRequired,
    epicId: PropTypes.string.isRequired,
  };

  state = {
    loading: true,
  };

  getNav(){
    return useNavigation();
  }

  handleLoad = () => {
    this.setState({ loading: false });
  };

  render() {
    const { fullname, image, linkText, onPressLinkText, epicId, prop } = this.props;
    const { loading } = this.state;
    
    return (
      <View>
        <AuthorRow
          fullname={fullname}
          linkText={linkText}
          onPressLinkText={onPressLinkText}
        />
        <TouchableHighlight onPress={() => this.getNav().navigate('Pager')} underlayColor="white">
          <View style={styles.image}>
            {loading && (
              <ActivityIndicator style={StyleSheet.absoluteFill} size={'large'} />
            )}
            <Image
              style={StyleSheet.absoluteFill}
              source={image}
              onLoad={this.handleLoad}
            />
          </View>
        </TouchableHighlight>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  image: {
    aspectRatio: 1,
    backgroundColor: 'rgba(0,0,0,0.02)',
  },
});

从上面的代码中,尝试使用:

从 'react-navigation-hooks' 导入 { useNavigation };

getNav(){ 返回 useNavigation(); }

this.getNav().navigate('Pager')

它错误我们的陈述:不变违规:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用。

如何使用“useNavigation()”导航或如何在组件中获取“this.props.navigation”引用? (我是 React Native 新手,请帮我理解)

更新

我尝试使用“this.props.navigation”,但它给了我未定义的错误:

【问题讨论】:

  • 你不能在基于类的组件中使用钩子,把它变成函数式组件。您可以将导航作为道具从父组件传递给自定义组件。
  • 如何将导航作为道具传递?
  • 你能更新你的新代码吗? check this may help

标签: android ios react-native react-native-android react-native-ios


【解决方案1】:

您不能在 Class 组件中使用钩子将您的类组件转换为功能组件或通过将导航道具传递给您的组件来使用导航对象进行导航this.props.navigation.navigate('screenName')

【讨论】:

  • getNav(){ const {navigate} = this.props.navigation; navigate('Pager'); } 即使我在上面尝试,它也会给我 TypeError: undefined is not an object (evalating this.props.navigation.navigate)
  • 我有同样的问题,在互联网上没有找到如何访问类组件中的导航。
【解决方案2】:

这是你的错误

错误

onPress={() => this.getNav().navigate('Pager')

替换为

onPress={() => this.props.navigation.navigate('Pager')

这里是例子

https://reactnavigation.org/docs/navigating/

https://medium.com/@marizu_makozi/navigating-between-screens-or-activities-using-react-navigation-library-68d57657d81

另一个示例代码

class FirstScreen extends React.Component {
  static navigationOptions = {
    title: 'First',
  }
  componentDidMount(){
    const {navigate} = this.props.navigation;
    navigate('Second');
    fetch('http://apiserver').then( (response) => {
      navigate('Second');
    });
  }
  render() {
    return (
      <AppLogo />
    );
  }
}

const AppNavigator = StackNavigator({
  First: {
    screen: FirstScreen,
  },
  Second: {
    screen: SecondScreen,
  },
});

【讨论】:

  • 因为我想点击,我尝试了getNav(){ const {navigate} = this.props.navigation; navigate('Pager'); } 它给了我 TypeError: undefined is not an object (evaluating this.props.navigation.navigate)
【解决方案3】:
    //In Card component remove this
    //import { useNavigation } from 'react-navigation-hooks';

    //Add this line
    import {withNavigation} from 'react-navigation';

    class Card extends React.Component {

      static propTypes = {
        fullname: PropTypes.string.isRequired,
        image: Image.propTypes.source.isRequired,
        linkText: PropTypes.string.isRequired,
        onPressLinkText: PropTypes.func.isRequired,
        epicId: PropTypes.string.isRequired,
      };

      state = {
        loading: true,
      };

    //Remove this
    //  getNav(){
     //   return useNavigation();
      //}

      handleLoad = () => {
        this.setState({ loading: false });
      };

      render() {
        const { fullname, image, linkText, onPressLinkText, epicId, prop } = this.props;
        const { loading } = this.state;

        return (
          <View>
            <AuthorRow
              fullname={fullname}
              linkText={linkText}
              onPressLinkText={onPressLinkText}
            />
            <TouchableHighlight onPress={() =>  
//Make change like this
 this.props.navigation.navigate('Pager')} underlayColor="white">
              <View style={styles.image}>
                {loading && (
                  <ActivityIndicator style={StyleSheet.absoluteFill} size={'large'} />
                )}
                <Image
                  style={StyleSheet.absoluteFill}
                  source={image}
                  onLoad={this.handleLoad}
                />
              </View>
            </TouchableHighlight>
          </View>
        );
      }
    }

    const styles = StyleSheet.create({
      image: {
        aspectRatio: 1,
        backgroundColor: 'rgba(0,0,0,0.02)',
      },
    });
//Make change like this
    export default withNavigation(Card)

【讨论】:

  • 很好的解决方案。为我工作
【解决方案4】:

@sayog 你违反了钩哥的规则。 你能试试这个吗?

const [loading, setLoading] = useState(false); const navigation = useNavigation();

确保将其放在您的州声明之后

注意:不要为 Hook 使用类组件。使用函数式组件进行钩子

【讨论】:

  • 在我的情况下,我也不得不把它放在 useEffect 之后
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 2022-11-19
  • 1970-01-01
  • 2021-07-02
  • 2019-01-29
相关资源
最近更新 更多