React + TypeScript 默认 Props 的处理
Posted wayou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React + TypeScript 默认 Props 的处理相关的知识,希望对你有一定的参考价值。
React 中的默认 Props通过组件的 以下示例来自 React 官方文档 - Default Prop Values: class Greeting extends React.Component
render()
return (
<h1>Hello, this.props.name</h1>
);
// Specifies the default values for props:
Greeting.defaultProps =
name: ‘Stranger‘
;
// Renders "Hello, Stranger":
ReactDOM.render(
<Greeting />,
document.getElementById(‘example‘)
); 如果编译过程使用了 Babel 的 transform-class-properties 插件,还可以这么写: class Greeting extends React.Component
static defaultProps =
name: ‘stranger‘
render()
return (
<div>Hello, this.props.name</div>
)
加入 TypeScript加入 TypeScript 后 interface Props
name?: string;
class Greeting extends React.Component<Props, >
static defaultProps =
name: "stranger",
;
render()
return <div>Hello, this.props.name</div>;
此时不支持直接通过类访问 // ??Property ‘defualtProps‘ does not exist on type ‘typeof Greeting‘.ts(2339)
Greeting.defualtProps =
name: "stranger",
; 默认属性的类型上面虽然实现了通过 class Greeting extends React.Component<Props, >
static defaultProps =
name: "stranger",
// 并不会报错
+ foo: 1,
+ bar: ,
;
// ...
同时对于同一字段,我们不得不书写两次代码。一次是定义组件的 为了后面演示方便,现在给组件新增一个必填属性 interface Props
age: number;
name?: string;
class Greeting extends React.Component<Props, >
static defaultProps =
name: "stranger",
;
render()
const name, age = this.props;
return (
<div>
Hello, name, my age is age
</div>
);
通过可选属性抽取出来,利用 所以优化后的代码成了: const defaultProps =
name: "stranger",
;
type Props =
age: number;
& Partial<typeof defaultProps>;
class Greeting extends React.Component<Props, >
static defaultProps = defaultProps;
render()
const name, age = this.props;
return (
<div>
Hello, name, my age is age
</div>
);
注意我们的 当我们更新了 默认值的判空检查优化讲道理,如果属性提供了默认值,在使用时,可不再需要判空,因为其一定是有值的。但 TypeScript 在编译时并不知道,因为有默认值的属性是被定义成可选的 比如我们尝试访问 class Greeting extends React.Component<Props, >
static defaultProps = defaultProps;
render()
const name = this.props;
return (
<div>
/* ??Object is possibly ‘undefined‘.ts(2532) */
name length is name.length
</div>
);
因为此时我们的 type Props =
age: number;
& Partial<typeof defaultProps>;
// 相当于:
type Props =
age: number;
name?: string;
; 修正方法有多个,最简单的是使用非空判定符/Non-null assertion operator。 非空判定符- name length is name.length
+ name length is name!.length 这意味着每一处使用的地方都需要做类似的操作,当程序复杂起来时不太可控。但多数情况下应付日常使用,这样已经够了。 类型转换因为组件内部有默认值的保证,所以字段不可能为空,因此,可对组件内部使用非空的属性类型来定义组件,而对外仍暴露原来的版本。 const Greeting = class extends React.Component<
- Props,
+ Props & typeof defaultProps,
>
static defaultProps = defaultProps;
render()
const name = this.props;
return (
<div>
- name length is name!.length
+ name length is name.length
</div>
);
-;
+ as React.ComponentClass<Props>; 通过 通过高阶组件的方式封装默认属性的处理通过定义一个高阶组件比如 function withDefaultProps<P extends object, DP extends Partial<P>>(
dp: DP,
component: React.ComponentType<P>,
)
component.defaultProps = dp;
type RequiredProps = Omit<P, keyof DP>;
return (component as React.ComponentType<any>) as React.ComponentType<
RequiredProps & DP
>;
然后我们的组件则可以这样来写: const defaultProps =
name: "stranger",
;
interface Props
name: string;
age: number;
const _Greeting = class extends React.Component<Props, >
public render()
const name = this.props;
return <div>name length is name.length</div>;
;
export const Greeting = withDefaultProps(defaultProps, _Greeting); 这种方式就比较通用一些,将 相关资源 |
以上是关于React + TypeScript 默认 Props 的处理的主要内容,如果未能解决你的问题,请参考以下文章
Eslint:功能组件中的默认道具问题(Typescript - React)
React + TypeScript 默认 Props 的处理
使用 Typescript 的 React 组件中的默认函数值