React Native Typescript Typing for "Backwards" ScrollView

Posted

技术标签:

【中文标题】React Native Typescript Typing for "Backwards" ScrollView【英文标题】: 【发布时间】:2020-10-20 22:02:14 【问题描述】:

我有一个ScrollView,它首先用作 javascript,然后也用作 TypeScript;这个ScrollView 使用ref 属性来捕获ScrollView 的引用,然后调用它的一个函数scrollToEnd()。但我最近加强了我的 linting,我需要找出正确的方法来输入这个引用属性实例。

我从这个开始:

import React from "react";
import ScrollView, StyleProp, ViewStyle from "react-native";

const standardStyle = flex:1, backgroundColor:'black';

export default class ViewClass 
    static produceBackwardScrollingView(customStyle : StyleProp<ViewStyle>, contents : any, horizontal : boolean) 
        let scrollView : any;
        return (
            <ScrollView
                nestedScrollEnabled=true
                ref=ref => 
                scrollView = ref
            
                onContentSizeChange=() => scrollView.scrollToEnd(animated: true)
                style=[standardStyle, customStyle]
                horizontal=horizontal>contents</ScrollView>
        );
    

经过大量与类型的斗争,我想出了这个我认为方向正确的方法,但我仍然遇到 TypeScript 错误。

import React from "react";
import ScrollView, StyleProp, ViewStyle from "react-native";

const standardStyle = flex:1, backgroundColor:'black';

export default class ViewClass 
    static produceBackwardScrollingView(customStyle : StyleProp<ViewStyle>, contents : any, horizontal : boolean) 
        let scrollView : React.RefObject<ScrollView> | ScrollView | null = React.createRef();
        return (
            <ScrollView
                nestedScrollEnabled=true
                ref=ref => 
                    // below: scrollView maybe assigned "ScrollView" or "null"
                    scrollView = ref
                
                // below: scrollView is possibly null
                // also below: "Property 'scrollToEnd' does not exist on type 'ScrollView | RefObject<ScrollView>'."
                onContentSizeChange=() => scrollView.scrollToEnd(animated: true)
                style=[standardStyle, customStyle]
                horizontal=horizontal>contents</ScrollView>
        );
    

我的场景当然使用ScrollView,所以我想是否有更好的方法可以让ScrollView 从底部开始,这可能会在这种情况下修复我的代码。但我认为这个问题是可以概括的,因为我的主要问题是我无法弄清楚我的对象引用需要什么类型以及如何在其上调用函数。

注意:我还是 React Native 和 TypeScript 的新手,所以我可能会很慢。

【问题讨论】:

【参考方案1】:

您的代码将 ref 对象的值与 ref 对象本身混为一谈。 ref 是具有属性current 的对象,其中包含您保存的值。您的类型let scrollView: React.RefObject&lt;ScrollView&gt; | ScrollView 表示它可以是组件本身该组件的引用。这就是为什么您会收到所有这些错误。

有多种方法可以实现 refs,但让我们坚持您正在做的事情,即使用 React.createRef 创建 ref。这将创建 一个 ref 对象,我们用它来存储组件 ref。为了清楚起见,我将把它重命名为 scrollRef

const scrollRef = React.createRef<ScrollView>(); // has type React.RefObject<ScrollView>

在回调中使用 ref 时,需要使用 scrollRef.current 来获取 ScrollView 对象。 React.RefObject&lt;ScrollView&gt;['current'] 的值可以是ScrollView,也可以是null,所以在调用scrollToEnd 之前,我们需要一个可选的链接?.

onContentSizeChange=() => scrollRef.current?.scrollToEnd(animated: true)

对于ScrollViewref 属性,我们可以只传递整个 ref 对象。

ref=scrollRef

将所有这些放在一起,我们得到:

export default class ViewClass 
    static produceBackwardScrollingView(customStyle : StyleProp<ViewStyle>, contents : any, horizontal : boolean) 
        const scrollRef = React.createRef<ScrollView>();
        return (
            <ScrollView
                nestedScrollEnabled=true
                ref=scrollRef
                onContentSizeChange=() => scrollRef.current?.scrollToEnd(animated: true)
                style=[standardStyle, customStyle]
                horizontal=horizontal>contents</ScrollView>
        );
    

Typescript Playground Link

【讨论】:

就像魔术一样!你说得对,我在贬低 TypeScript 推断类型的能力。很简约。可选的链接 ?. 很棒,我不知道 TypeScript 有一个 Elvis 运算符。再次感谢琳达。

以上是关于React Native Typescript Typing for "Backwards" ScrollView的主要内容,如果未能解决你的问题,请参考以下文章

React-native:如何在 React-native 中使用(和翻译)带有 jsx 的 typescript .tsx 文件?

[React Native] Up & Running with React Native & TypeScript

React-native:从 javascript 迁移到 typescript

已有的react-native 项目配置TypeScript

在后端、react 和 react-native 客户端之间共享 typescript 代码

react native 可以使用typescript开发吗