如何使用TypeScript在React Native中将ForwardRef与FunctionComponent一起使用 [英] How to use forwardRef with FunctionComponent in React Native using TypeScript

查看:220
本文介绍了如何使用TypeScript在React Native中将ForwardRef与FunctionComponent一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过许多文档和示例,但是我似乎仍然不太了解如何将 forwardRef 与React Native中带有TypeScript的功能组件一起使用.下面是一个示例,其中我使用自定义函数创建一个 MyCustomComponent ,我尝试通过创建引用从父函数调用该函数.但是,由于ref的定义不正确且 null ,我显然收到一条错误消息,告诉我该函数不存在.请帮助我了解如何在React Native中正确使用 forwardRef .预先感谢!

I've looked at many of the docs and examples but I still can't seem to quite understand how to use forwardRef with a functional component with TypeScript in React Native. Below is an example where I create a MyCustomComponent with a custom function that I try to call from the parent by creating a ref. However, since the ref is incorrectly defined and null, I obviously get an error message telling me that the function doesn't exist. Please help me understand how to properly use forwardRef in React Native. Thanks in advance!

interface MyCustomComponentProps {
    title: string
}

const MyCustomComponent: React.FunctionComponent<MyCustomComponentProps> = React.forwardRef((props, ref) => {
    const coolAlert = () => {
        Alert.alert('Hey!', 'This was called from MyCustomComponent')
    }
    return (
        <View>
            <Text>{props.title}</Text>
        </View>
    )
})

export default function App () {
    const MyCustomComponentRef = useRef()
    return (
        <SafeAreaView>
            <MyCustomComponent ref={MyCustomComponentRef} title='Hello World' />
            <TouchableOpacity
                onPress={() => {
                    MyCustomComponentRef.coolAlert()
                }}>
                <Text>Click Me</Text>
            </TouchableOpacity>
        </SafeAreaView>
    )
}

推荐答案

转发参考

引用确实会造成混乱,因为有多种处理方法,而且人们不了解引用对象之间的区别( React.MutableRefObject React.RefObject )和ref值,该值存储在ref对象的 .current 属性中.您在这里犯了这个错误,以及一些缺少或不正确的打字稿类型.

Forwarding the Ref

Refs can be really confusing because there are multiple ways to handle them and because people aren't aware of the difference between the ref object (React.MutableRefObject or React.RefObject) and the ref value, which is stored on the .current property of the ref object. You've made that mistake here, along with some missing or incorrect typescript types.

useRef< T> 是一个通用钩子,其中值 T 指示将存储哪种类型的值.我们需要告诉 App 我们打算使用 coolAlert 方法存储某些内容.实际上,稍后我们会看到我们需要将引用保持不变,因此我们将改为使用 createRef< T> .

useRef<T> is a generic hook where the value T tells up what type of value will be stored. We need to tell App that we intend to store something with a coolAlert method. Actually we'll see later on that we need our ref to be immutable so we we'll use createRef<T> instead.

interface MyRef {
  coolAlert(): void;
}

const MyCustomComponentRef = createRef<MyRef>();

当我们调用 onPress 时,我们需要访问ref对象的当前值.通过将泛型添加到 createRef 中,打字稿已经知道该值为 MyRef undefined .我们可以使用可选的链接?.运算符来调用 coolAlert .

When we call onPress, we need to access the current value of the ref object. By adding the generic to createRef, typescript already knows that this value is either MyRef or undefined. We can call coolAlert with the optional chaining ?. operator.

onPress={() => MyCustomComponentRef.current?.coolAlert()}

现在,我们需要在 MyCustomComponent 上做一些工作.您将其分配为 React.FunctionComponent< MyCustomComponentProps> 类型是错误的,因为功能组件不具备我们所需的ref转发知识.

Now we need to do some work on MyCustomComponent. You've erred by assigning it the type React.FunctionComponent<MyCustomComponentProps> because a function component doesn't have the knowledge about ref forwarding that we need.

function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;

MyCustomComponent 的类型应该是 forwardRef 中的复杂返回类型.但是我们不需要自己分配该类型,我们只需要将泛型 T P 传递给 forwardRef 函数调用即可. T 是裁判的类型, P 是道具的类型.

The type for MyCustomComponent should be that complicated return type from forwardRef. But we don't need to assign that type ourselves, we just need to pass the generics T and P to the forwardRef function call. T is the type of the ref and P is the type of the props.

const MyCustomComponent = React.forwardRef<MyRef, MyCustomComponentProps>(...

确定,所以我们摆脱所有打字稿错误!耶!除了...高举.它实际上并没有做任何事情.所有这些,它仍然不起作用.我讨厌裁判.推荐人不好.

Ok so we got rid of all the typescript errors! Yay! Except...hold up. It doesn't actually do anything. All of that and it still doesn't work. I hate refs. Refs are bad.

我们将引用转发给了 MyCustomComponent ,后者现在可以访问转发的引用并将其附加到DOM组件.但是我们不希望它附加到DOM元素,我们希望它附加到 MyCustomComponent .但是我们真的不能做到这一点.

We forwarded the ref to MyCustomComponent, who now has access to the forwarded ref and can attach it to a DOM component. But we don't want it attached to the DOM element, we want it attached to MyCustomComponent. But we can't really do that.

默认情况下,您不能在功能组件上使用ref属性,因为它们没有实例 [docs]

我们必须使用一个名为 useImperativeHandle 的钩子,该钩子看起来像是一种黑客解决方案,甚至文档都说不要这样做".是的,我讨厌裁判.

We have to make use of a hook called useImperativeHandle which feels like a hack solution and even the docs say "don't do this". Yup, I hate refs.

useImperativeHandle自定义使用ref时公开给父组件的实例值.一如既往,在大多数情况下,应避免使用ref的命令式代码. useImperativeHandle应该与forwardRef一起使用. [docs]

useImperativeHandle customizes the instance value that is exposed to parent components when using ref. As always, imperative code using refs should be avoided in most cases. useImperativeHandle should be used with forwardRef. [docs]

我们必须通过 useImperativeHandle 公开我们的 coolAlert 方法.

We have to expose our coolAlert method through useImperativeHandle.

useImperativeHandle(ref , () => ({coolAlert}));

现在它实际上有效,最后!

这篇关于如何使用TypeScript在React Native中将ForwardRef与FunctionComponent一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆