react+typescript正确的开发姿势之正确使用hooks之useState

写在前面

要想在react + typescript 项目中正确的使用 hooks ,请务必掌握泛型的使用,关于泛型的讲解,我在上一篇博文中详细的进行了介绍,如果你还不了解 typescript 中的泛型请看上一篇:正确认识typescript中的泛型

如何结合typescript正确使用hooks

在react中使用函数式组件,难免会使用到hooks,hooks赋予了函数式组件可以像 class 组件那样拥有状态的能力,那么如何结合typescript正确的使用hooks呢?

在react + typescript项目中正确使用useState

如果想编写一个 Header 组件,使其具备一个登录和退出的功能,登录的时候,显示一些提示已经登录的文字,退出的时候显示欢迎的文字,那么我们很容易知道:如果使用函数式组件来编写此 Header 组件,那么就一定会用到 useState ,因为登录与否的状态是该组件自身的状态,所以就会用到hooks中的 useState 来赋予函数式组件状态。如下:

// Header.tsx
import React, {
    
     useState } from 'react'

export default function Header() {
    
    
    const [isLogin, setIsLogin] = useState(false);

    const _logout = () => {
    
    
        setIsLogin(false)
    }

    const _login = () => {
    
    
        setIsLogin(true)
    }

    return (
        <div>
            {
    
    isLogin ? <p>You have logined in!</p> : <p>welcome, guest!</p>}
            {
    
    isLogin ? <button onClick={
    
    _logout}>退出</button> : <button onClick={
    
    _login}>登录</button>}
        </div>
    )
}

其实在第五行const [isLogin, setIsLogin] = useState(false);使用useState赋予初始值false的时候,后续在调用setIsLogin函数时,ts 编译器就会自动推断你传入的参数是不是boolean类型的,若不是,则会报错。第五行,我们也可以进行显式的进行限制,传入泛型,就像这样const [isLogin, setIsLogin] = useState<boolean>(false);

我们也可以把要显示的文案也抽象成为组件的一个状态,这样我们就不需要再写三元表达式了:

import React, {
    
     useState } from 'react'

export default function Header() {
    
    
    const [isLogin, setIsLogin] = useState<boolean>(false);
    const [text, setText] = useState<string>('');

    const _logout = () => {
    
    
        setIsLogin(false);
        setText('welcome, guest!');
    }

    const _login = () => {
    
    
        setIsLogin(true);
        setText('You have logined in!');
    }

    return (
        <div>
            <p>{
    
     text }</p>
            {
    
    isLogin ? <button onClick={
    
    _logout}>退出</button> : <button onClick={
    
    _login}>登录</button>}
        </div>
    )
}

这里的函数setIsLogin只能传入布尔类型的值,函数setText只能传入 string 类型的值,传别的类型都会报错。
这里的两个状态比较简单,一个是布尔类型,一个是 string 类型,可能体现不出typescript的强大之处,那么我们再增加一个状态用户信息:const [user, setUser] = useState<UserType | null>(null),完整代码如下:

import React, {
    
     useState } from 'react'

type UserType = {
    
    
    name: string;
    age: number;
    addr: string;
}

export default function Header() {
    
    
    const [isLogin, setIsLogin] = useState<boolean>(false);
    const [text, setText] = useState<string>('');
    const [user, setUser] = useState<UserType | null>(null)

    const _logout = () => {
    
    
        setIsLogin(false);
        setText('welcome, guest!');
        setUser(null)
    }

    const _login = () => {
    
    
        setIsLogin(true);
        setText('You have logined in!');
        setUser({
    
    
            name: '小明',
            age: 18,
            addr: '深圳市南山区深圳湾河里'
        })
    }

    return (
        <div>
            <p>{
    
     text }</p>
            <p>username is {
    
    user?.name}, user's age is {user?.age}, user's address is {
    
    user?.addr}</p>
            {
    
    isLogin ? <button onClick={
    
    _logout}>退出</button> : <button onClick={
    
    _login}>登录</button>}
        </div>
    )
}

我们给useState显式的传入泛型UserType或者null,就表示我们在后续调用setUser的时候,就只能传入UserType 类型的值或者 null 类型的值,否则ts编译器就会告诉你传值错误。这样做,我们在开发过程中可以省去了很多麻烦,可维护性也更好。

代码地址及文件路径

注:
本文代码github仓库地址:ts中正确使用useState
文件路径:src/components/Header.tsx

猜你喜欢

转载自blog.csdn.net/weixin_40920953/article/details/122637277