前言
在编写react组件的时候,为了兼容一些分支逻辑,我们经常会给组件的props设置一些默认值,但是有些默认值的写法会导致一些潜在的问题,比如无法推断类型,本文将对几种设置默认值的写法进行分析,总结其优劣。
解构props时设置默认值
interface IProps { name: string; age?: number; } const DefaultProps = (props: IProps) => { const { age = 10, name } = props; console.log(age + 10); return <div />; };
这种情况应该是我们经常会写的一种方式,在解构props时对可选类型设置默认值,在 hook 组件中这种方法很简洁,但是在 class 组件中,凡是用到这些参数的方法,我们都需要设置一次默认值,组件复杂度比较高的时候,这样写就比较容易出错。
interface IProps { name: string; age?: number; } class DefaultProps extends Component<IProps, {}> { func1() { const { age = 10, name } = this.props; //... } func2() { const { age = 10, name } = this.props; //... } render() { return <div />; } }
所以解构时设置默认值推荐在 hook 组件中使用,不推荐在 class 组件中使用
使用defaultProps
React的组件有一个属性 defaultProps ,我们可以通过这个属性来给组件设置默认参数。
比如类组件
interface IProps { name: string; age?: number; } class DefaultProps extends Component<IProps, {}> { defaultProps = { age: 20, }; func1() { const { age, name } = this.props; } func2() { const { age, name } = this.props; } render() { const { age, name } = this.props; console.log(age); //20 return <div />; } }
这样可以避免第一种类组件设置默认值时,需要在每个地方都单独设置的冗余情况,但是也带来了新的弊端,那就是即使设置了默认值,在使用的时候也不能推断出准确的类型,依然会提示变量有 undefined 的风险
所以,如果需要更准确的类型推断,这里还需要对类型进行额外的处理.
进行额外的类型校验
因为赋了默认值,我们希望能得到更准确的类型推断,所以我们可以将默认值的类型单独抽离,再合并到Props的类型中,以达到更好的类型推断.
interface IProps { name: string; age?: number; } class DefaultProps extends Component<Required<IProps>, {}> { defaultProps: Partial<IProps> = { age: 20, }; render() { const { age } = this.props; console.log(age); return <div />; } }
这里我们将所有属性全部设置成可选,然后根据需要设置默认值,在初始化的时候将props设置为 Required 这样就能在使用时准确推断类型。
值得注意的是,这里没有检测是否所有可选类型都有默认值,如果所有的可选类型都需要默认值,可以再加上这样一个工具类型,筛选出所有可选类型。
type Filter<T> = { [K in keyof T as undefined extends T[K] ? K : never]: T[K]; };
于是代码变成了
interface IProps { name: string; age?: number; sex?: string; } type Filter<T> = { [K in keyof T as undefined extends T[K] ? K : never]: T[K]; }; class DefaultProps extends Component<Required<IProps>, {}> { defaultProps: Required<Filter<IProps>> = { age: 20, sex:'male' }; render() { const { age } = this.props; console.log(age); return <div />; } }
如果不写的话就会提示
结语
原文地址:https://juejin.cn/post/7225816951212589117
查看更多关于浅谈React组件props默认值的设置的详细内容...