首页 > 解决方案 > React Native Typescript Typing for "Backwards" ScrollView

问题描述

我有一个ScrollView首先作为 JavaScript 工作,然后也作为 TypeScript 工作的工具;thisScrollView使用该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 的新手,所以我可能会很慢。

标签: javascriptreactjstypescriptreact-nativemobile

解决方案


您的代码将 ref 对象的值与 ref 对象本身混合在一起。ref 是一个对象,其属性current包含您保存的值。您的类型let scrollView: React.RefObject<ScrollView> | ScrollView表示它可以是组件本身,也可以是该组件ref。这就是为什么你会收到所有这些错误。

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

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

当您在回调中使用 ref 时,您需要使用scrollRef.current来获取ScrollView对象。的值React.RefObject<ScrollView>['current']要么是 a ,要么ScrollView可以是,所以我们在调用 之前null需要一个可选链。?.scrollToEnd

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

对于 的ref道具ScrollView,我们可以只传递我们的整个 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>
        );
    }
}

打字稿游乐场链接


推荐阅读