在 React Native 中的类中挂钩

Posted

技术标签:

【中文标题】在 React Native 中的类中挂钩【英文标题】:Hook inside a Class in React Native 【发布时间】:2020-10-07 12:46:08 【问题描述】:

我很想知道如何使用组件内的useNavigation() 函数从 React Navigation 模块在屏幕之间导航。根据文档,您必须通过在我的标签(此处)中包含 onPress 来包含 useNavigation() 函数。问题 是它向我显示以下错误:'不变违规:无效调用。 Hook 只能在函数组件的主体内部调用。'

我的 React Native 组件:

import React,  Component  from 'react';
import View, StyleSheet, Image, TouchableOpacity from "react-native";
import  Text  from 'react-native-elements';
import  LinearGradient  from 'expo-linear-gradient';
import PropTypes from 'prop-types';
import  useNavigation  from '@react-navigation/native';

export default class HorizontalCard extends Component 
    static propTypes = 
        screen: PropTypes.string,
        title: PropTypes.string,
        desc: PropTypes.string,
        img: PropTypes.string,
      
    render() 
        const navigation = useNavigation();
        return (
             <TouchableOpacity onPress=() => navigation.navigate(this.props.screen) style=styles.container>
                <View style=styles.card_discord>
                    <Image style=styles.card_discord_img source=uri: this.props.img />
                        <LinearGradient
                            start=[1.0, 0.5]
                            end=[0.0, 0.5]
                            colors=['rgba(42, 159, 255, 0.2)', '#333333', '#333333']
                            style=styles.FadeAway>
                            <View style=styles.FadeAway>
                                <Text h4 style=styles.FadeAway_h2>this.props.title</Text>
                                <Text style=styles.FadeAway_p>this.props.desc</Text>
                            </View>
                        </LinearGradient>
                </View>   
            </TouchableOpacity>
        )
    

谢谢。 问候,

昆汀

【问题讨论】:

【参考方案1】:

如果你想使用hooks,你不能将你的组件实现为classes

所以,如果你想使用hooks,你应该将你的组件实现为functions,因为hooks只能在function component的主体内调用。

所以,你的组件应该如下。

将组件实现为 s FUNCTION 并使用 HOOKS。

import React from 'react';
import  View, StyleSheet, Image, TouchableOpacity  from 'react-native';
import  Text  from 'react-native-elements';
import  LinearGradient  from 'expo-linear-gradient';
import PropTypes from 'prop-types';
import  useNavigation  from '@react-navigation/native';

export function HorizontalCard(props) 
  const navigation = useNavigation();

  return (
    <TouchableOpacity
      onPress=() => navigation.navigate(props.screen)
      style=styles.container>
      <View style=styles.card_discord>
        <Image style=styles.card_discord_img source= uri: props.img  />
        <LinearGradient
          start=[1.0, 0.5]
          end=[0.0, 0.5]
          colors=['rgba(42, 159, 255, 0.2)', '#333333', '#333333']
          style=styles.FadeAway>
          <View style=styles.FadeAway>
            <Text h4 style=styles.FadeAway_h2>
              props.title
            </Text>
            <Text style=styles.FadeAway_p>props.desc</Text>
          </View>
        </LinearGradient>
      </View>
    </TouchableOpacity>
  );


HorizontalCard.propTypes = 
  screen: PropTypes.string,
  title: PropTypes.string,
  desc: PropTypes.string,
  img: PropTypes.string,
;

但是,如果您仍需要将组件实现为 class,则可以忘记使用 useNavigation 挂钩并继续使用 this.props.navigation

在这种情况下,您的组件应如下所示。

将组件实现为 CLASS 且没有 Hooks

import React,  Component  from 'react';
import  View, StyleSheet, Image, TouchableOpacity  from 'react-native';
import  Text  from 'react-native-elements';
import  LinearGradient  from 'expo-linear-gradient';
import PropTypes from 'prop-types';

export default class HorizontalCard extends Component 
  constructor(props) 
    super(props);
  

  static propTypes = 
    screen: PropTypes.string,
    title: PropTypes.string,
    desc: PropTypes.string,
    img: PropTypes.string,
  ;

  render() 
    return (
      <TouchableOpacity
        onPress=() => this.props.navigation.navigate(this.props.screen)
        style=styles.container>
        <View style=styles.card_discord>
          <Image
            style=styles.card_discord_img
            source= uri: this.props.img 
          />
          <LinearGradient
            start=[1.0, 0.5]
            end=[0.0, 0.5]
            colors=['rgba(42, 159, 255, 0.2)', '#333333', '#333333']
            style=styles.FadeAway>
            <View style=styles.FadeAway>
              <Text h4 style=styles.FadeAway_h2>
                this.props.title
              </Text>
              <Text style=styles.FadeAway_p>this.props.desc</Text>
            </View>
          </LinearGradient>
        </View>
      </TouchableOpacity>
    );
  

【讨论】:

非常感谢您的解决方案,其实我现在明白了! @SennenRandika 只是建议,基于类的版本可以通过包装在功能组件中与钩子一起使用,您可以在此处查看文档reactnavigation.org/docs/use-navigation @GuruparanGiritharan 是的......我没有意识到这一点。我认为如果我们想使用钩子,我们必须使用函数组件。感谢您在这里发表评论并让我知道。 :-) 不客气,我们会这样做,但对于导航,可以使用环绕解决方法:)【参考方案2】:

您不能在 Class 组件中使用钩子,正如错误中明确指出的那样。请查看React documentation

【讨论】:

【参考方案3】:

您也可以将您的类组件包装在一个函数组件中以使用钩子并通过道具获取它:

class MyBackButton extends React.Component 
  render() 
    // Get it from props
    const  navigation  = this.props;
  


// Wrap and export
export default function(props) 
  const navigation = useNavigation();

  return <MyBackButton ...props navigation=navigation />;

【讨论】:

以上是关于在 React Native 中的类中挂钩的主要内容,如果未能解决你的问题,请参考以下文章

带有 Flipper pod 和安装后挂钩的 React Native v0.62.2 中的问题

如何使用 React useRef 挂钩删除地图中的类

react-native-sqlite-storage 中的 React Native Async Await

React-Native:在另一个类中访问 TextField 值

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。 (React-hooks React-native)

在 React / React Native 中不是父/子的类之间共享和更新变量