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

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

问题描述

我已经查看了许多文档和示例,但我似乎仍然不太明白如何在 React Native 中将 forwardRef 与带有 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>
  )
}

推荐答案

转发参考

Refs 可能真的很令人困惑,因为有多种方法可以处理它们,而且人们不知道 ref 对象(React.MutableRefObjectReact.RefObjectcode>) 和 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 方法存储一些东西.实际上我们稍后会看到我们需要我们的 ref 是不可变的,所以我们将使用 createRef 代替.

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,打字稿已经知道该值是 MyRefundefined.我们可以使用可选的链接 ?. 运算符调用 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 类型,因为函数组件不具备我们需要的关于 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 的复杂返回类型.但是我们不需要自己分配那个类型,我们只需要将泛型 TP 传递给 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 属性,因为它们没有实例 [文档]

By default, you may not use the ref attribute on function components because they don’t have instances [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 一起使用.[文档]

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天全站免登陆