最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React中使用TypeScript参考指南

    正文概述 掘金(GoSolo)   2020-11-27   441

    JavaScript的问题之一是其动态类型化的性质,这意味着直到运行时才知道数据和变量类型。这可能有很多副作用。例如,由于变量可以是任何事实,这可能导致代码库混乱。

    为了解决此问题,Microsoft发布了TypeScript。TypeScript的首席架构师Anders Hejlsberg说:“What if we could strengthen JavaScript with the things that are missing for large scale application development, like static typing, classes [and] modules…? That’s what TypeScript is about.”//“如果我们可以利用大规模应用程序开发所缺少的东西(如静态类型,类[和]模块……)来增强JavaScript,该怎么办?这就是TypeScript的目的。”

    TypeScript立即成为使用最广泛的JavaScript静态类型版本。它使JavaScript开发人员能够静态键入数据和变量。很快,它就被引入React.js中,从而使React开发人员可以使用TypeScript编写其React应用。

    但这是有代价的:TypeScript类型和语法可能难以跟上,尤其是与React一起使用时。

    React具有许多功能,例如props, class components, function components, function params, components lifecycle hooks, and member properties。由于在TypeScript中键入这些内容并不容易,因此本文旨在为初学者和高级React开发人员提供快速参考和学习指南。

    通过这,您将能够在React中快速查找最佳实践和通用TS类型。准备?让我们开始吧。

    TypeScript类型

    TypeScript有一个typings文件夹,用于保存扩展名为* .d.ts的文件。这些文件包括推断值将采用何种形状的接口。这就是使TypeScript能够将数据类型引入JavaScript的原因。

    接口描述了值的形式:

    type AppState {
        propOne: number;
        propTwo: string
    }
    

    AppState描述其数据类型的值将是什么样。首先,我们推断它将是一个包含属性propOne和propTwo的对象,propTwo前者是数字类型,后者是字符串类型。分配一个布尔类型的propOne将导致TypeScript抛出TypeError。

    当我们在React项目中包含TypeScript时,每个React元素都有一个定义其形状的接口。让我们从函数组件开始。

    函数组件

    函数组件是正常的函数,它们在React中返回JSX元素,并用于创建视图。最初,它们是无状态的组件,但是随着React钩子(React hooks)的到来,它们可以变成有状态的和智能的

    定义React函数组件的React.FunctionComponent形状如下:

    function App: React.FunctionComponent<> {
        return (
            <>
                // ...
            </>
        )
    }
    

    我们也可以使用速记 React.FC:

    function App: React.FC<> {
        return (
            <>
                // ...
            </>
        )
    }
    

    React.FunctionComponent或React.FC明确描述函数组件的返回类型。

    我们可以在箭头中输入props定义<>。

    type AppProps = {
        message: string;
        age: number;
    };
    

    AppProps是传递给App的props将采用的接口,因此如果它可以接收props,我们可以在下面编写App组件:

    type AppProps {
        message: string;
        age: number;
    }
    
    function App: React.FC<AppProps>(props: AppProps) {
        return (
            <>
                // ...
            </>
        )
    }
    

    我们可以使用?在键入中设置可选值:

    type AppProps {
        message: string;
        age?: number;
    }
    

    现在,age属性变为可选。该App组件可以呈现,省略其props对象的年龄属性。

    我们可以在箭头内省略类型声明<>。

    function App<{message: string; age: number;}>({message: string; age: number;}: AppProps) {
        // ...
    }
    

    可以嵌入函数组件中的内部函数,如下所示:

    function App<{message: string; age: number;}>({message: string; age: number;}: AppProps) {
        // ...
    
        function clickHandler (val: number) {
            // ...
        }
    
        return (
            <>
                <button onClick={() => clickHandler(45)}            
            </>
        )
    }
    

    类组件

    类组件用于在React中创建视图。它们本质上是构建块。一个React应用程序可以包含许多应用程序,它们定义了一小部分UI应该如何显示。

    类组件具有生命周期挂钩,我们可以将其挂钩以在组件生命周期的任何状态下运行自定义代码。

    他们使用React.Component<>:

    class App extends React.Component<> {
        // ...    
    }
    

    Props 和 State

    您可以为类组件提供Props和State状态类型参数:

    type AppProps = {
        message: string;
        age: number;
    };
    
    type AppState = {
        id: number;
    };
    
    class App extends React.Component<AppProps, AppState> {
        state: AppState = {
            id: 0
        };
    
        // ...    
    }
    

    props类型AppProps插入在状态类型AppState之前的<>箭头之间。

    类方法

    如果您有用于类方法的参数,则可以键入参数:

    class App extends React.Component<AppProps, AppState> {
        state: AppState = {
            id: 0
        };
    
        clickHandler = (val: number) => {
            // ...
        }
    
        render() {
            return (
                <>
                    <button onClick={() => this.clickHandler(90)}>Click</button>
                </>
            )
        }
    }
    

    函数组件和defaultProps类型

    defaultProps用于定义传递给React组件的props参数的默认值。defaultProps当在运行时丢失了可能可用的props时,有助于防止错误。其中的值defaultValues立即成为props的值。

    React.FC包含defaultProps在函数组件中时会被丢弃,因为类型推断中的某些边缘情况在TypeScript中仍然是一个问题。

    这意味着props的使用与通常一样:

    type AppProps = { message: string; age: number } & typeof defaultProps;
    const defaultProps = {
        message: "",
        age: 0
    };
    
    function App(props: AppProps) {
        // ...
    };
    
    App.defaultProps = defaultProps;
    

    表单和事件

    表单通常用于收集内部状态的信息。它们主要用于登录和注册页面,因此提交的信息可以通过表单收集并发送到服务器进行处理。

    React.FormEvent 通常用于键入元素中的事件。

    class App extends React.Component<> {
        clickHandler = (e: React.FormEvent<HTMLButtonElement>) => {
            // ...
        }
    
        changeHandler = (e: React.FormEvent<HTMLInputElement>) => {
            // ...
        }
    
        render() {
            return (
                <div>
                    <button onClick={this.clickHandler}>Click</button>
                    <input type="text" onChange={this.changeHandler} />
                </div>
            )
        }
    }
    

    clickHandler和changeHandler参数e均具有React.FormEvent类型。

    我们可以省略使用React.FormEvent输入处理程序的参数,而改为输入处理程序的返回值。 这是使用React.ChangeEventHandler完成的:

    class App extends React.Component<> {
        clickHandler: React.FormEvent<HTMLButtonElement> = (e) => {
            // ...
        }
    
        changeHandler: React.FormEvent<HTMLInputElement> = (e) => {
            // ...
        }
    
        render() {
            return (
                <div>
                    <button onClick={this.clickHandler}>Click</button>
                    <input type="text" onChange={this.changeHandler} />
                </div>
            )
        }
    }
    

    React.ChangeEvent 是可用于输入事件处理程序参数的事件类型:

    class App extends React.Component<> {
        clickHandler = (e: React.ChangeEvent<HTMLButtonElement>) => {
            // ...
        }
    
        changeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
            // ...
        }
    
        render() {
            return (
                <div>
                    <button onClick={this.clickHandler}>Click</button>
                    <input type="text" onChange={this.changeHandler} />
                </div>
            )
        }
    }
    

    注意,T是注册事件的元素的类型。

    Button

    这描述了button元素的React.ChangeEvent类型。按钮是HTMLButtonElement类的实例。在这里,T将是HTMLButtonElement,而React.ChangeEvent将是React.ChangeEvent。

    Inputs

    这描述了React.ChangeEvent所有输入元素:“text,” “password,” “color,” “button,” “media,”等。它们都是HTMLInputElement类的实例。对于所有types= [“text”, “password”, etc]

    T将是HTMLTnputElement。React.ChangeEvent将是React.ChangeEvent。

    TextArea

    这是指文本区域元素的React.ChangeEvent,并且文本区域元素是HTMLTextAreaElement的实例。

    T将是HTMLTextAreaElement。 React.ChangeEvent将是React.ChangeEvent。

    Select

    Select元素用于创建带有选择选项的下拉列表。选择元素是HTMLSelectElement的实例。

    T将是HTMLSelectElement。React.ChangeEvent将是React.ChangeEvent。

    Form

    表单元素从DOM收集信息。表单元素是HTMLFormElement的实例。T将是HTMLFormElement。React.ChangeEvent将是React.ChangeEvent。

    Video, Audio

    视频用于在浏览器上播放视频。video元素是HTMLVideoElement的实例。这描述了如何在Form元素中设置React.ChangeEvent。

    T将是HTMLVideoElement。 React.ChangeEvent将是React.ChangeEvent。

    依次,音频用于在浏览器中播放音频文件(mp3,aac等)。音频元素是HTMLAudioElement的实例。

    T将是HTMLAudioElement。 React.ChangeEvent将是React.ChangeEvent。

    React.SyntheticEvent

    当您不关心事件的类型时,可以使用以下类型:

    class App extends React.Component<> {
        submitHandler = (e: React.SyntheticEvent) => {
            // ...
        }
    
        render() {
            return (
                <form onSubmit={this.submitHandler}>
                    ...
                </form>
            )
        }
    }
    

    Hooks

    Reactv16.8 +支持Hooks。它们允许我们在函数组件中使用状态。

    useState

    这用于设置函数组件中的状态,并且该状态在组件的整个生命周期中都保持活动状态。

    const [state, setState] = useState(0)
    

    我们可以推断state为数字,而setState为推断数字的函数。

    const [state, setState] = useState<number, (v: boolean) => : void >(0)
    

    如果state带一个对象:

    type StateObject = {
        loading: boolean
    }
    
    const [state, setState] = useState<StateObject, (boolean) => : void >({loading: true})
    

    通常,useState初始值为null。我们可以使用联合类型来显式声明类型,如下所示:

    const [state, setState] = useState<StateObject | null, (boolean) => : void >(null)
    

    这个StateObject | null告诉TypeScript状态可以是StateObject类型或null类型。

    useReducer

    useReducer允许我们维护状态并同时从我们的函数组件向store分发操作。它具有一个初始状态和一个reducer函数:

    const intialState = {
        loggedIn: false
    }
    
    function reducer(state, action) {
        // ...    
    }
    
    const [state, dispatch ] = useReducer(initialState, reducer)
    

    我们可以定义state的类型,然后根据返回类型键入reducer函数。可以根据reducer函数上的action参数类型来输入调度:

    type LogginState = {
        loggedIn: boolean;
    };
    
    type ActionType = {
        type: string;
        payload: boolean;
    };
    
    const intialState: LogginState = {
        loggedIn: false
    }
    
    function reducer(state: LogginState, action: ActionType): LogginState {
        // ...    
    }
    
    const [state, dispatch ] = useReducer<LogginState, (v: ActionType) => : void>(initialState, reducer)
    

    useRef

    useRef允许我们访问React节点中的ref,并在组件的整个生命周期内对其进行维护。

    null类型主要传递给useRef,因此键入看起来像这样:

    const ref= useRef<HTMLElement | null>(null)
    

    我们可以更具体地说明我们要引用的元素类型:

    // this types useRef to button elements
    const buttonRef= useRef<HTMLButtonElement | null>(null)
    
    // this types useRef to input elements
    const inputRef= useRef<HTMLInputElement | null>(null)
    

    另外,useRef可用于React.Component:

    const inputRef= useRef<React.Component | null>(null)
    

    useContext

    useContext允许我们在函数组件的整个生命周期中创建和维护上下文。使用React Context API创建上下文。

    以下是使用useContext和createContext创建上下文的方法:

    const authContext = createContext({isAuth: true})
    const context = useContext(authContext)
    

    的默认值类型createContext将构成其参数类型的基础:

    type AuthType = {
        isAuth: boolean;
    };
    
    const authContext = createContext<AuthType>({isAuth: true})
    

    此外,useContext参数类型将为AuthType:

    const context = useContext<AuthType>(authContext)
    

    最后

    希望您发现本指南对您有帮助。


    起源地下载网 » React中使用TypeScript参考指南

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元