博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TypeScript 3.0 + React + Redux 最佳实践
阅读量:7183 次
发布时间:2019-06-29

本文共 2285 字,大约阅读时间需要 7 分钟。

首先声明, 这篇文章是想说明一下最新版本的 TypeScript(3.0) 的新特性带来的极大的 React 开发体验提升. 而不是如何利用 TypeScript 开发 React 应用.

这个特性就是对defaultProps的支持, 在 TypeScript 的 Wiki 中有说明, 具体可以参考这里: .


在3.0版本之前, 我们在开发 React 应用, 尤其是在配合 redux 一类 HOC 库的时候, 经常用到诸如 connect(TodoList), withRouter(TodoList) 之类的封装. 而这些函数其实都可以用装饰器的方式来调用, 比如:

export interface TodoListProps extends RouteComponentProps<{}> {  todos: Todo[];}@withRouter@connect(mapStateToProps)export class TodoList extends PureComponent
{ render() { return null }}

但是在结合 TypeScript 的时候, 这中间有个问题, 就是装饰器会自动注入一些 props 给组件, 这一部分属性不需要外部传入, 因此是可选的, 在strictNullCheck属性开启的时候, 就会出现属性冲突. 因为 TS 给不允许装饰器修改被装饰的对象的类型, 因此在 props 定义中为required属性依然为required.

比如对于上面的例子, 在实例化TodoList这个组件的时候, 必需要传入所有的TodoListProps所定义的属性, 否则会有TS2322错误.

而在 TS 3.0 中, 可以声明defaultProps属性来表明某些属性对外部组件而言是可选的. 比如:

@withRouter@connect((state) => ({ todos: state.todos })export class TodoList extends PureComponent
{ static defaultProps: TodoListProps render() { return null }}

这里的static defaultProps: TodoListProps表明, 所有的TodoList的 props TodoListProps 对外部组件都是可选的. 这就意味着外部组件可以什么属性都不用传也不会有错误. 同时内部而言所有的属性都是NotNullable.


综上, 通常情况下, 我们的一个组件会有一部分属性由装饰器注入, 而另一部分则需要外部实例化时传入, 因此, 可以将一个组件的 props 接口声明成两层结构, 第一层为由装饰器注入的部分, 第二层则为完整的属性接口, 然后将defaultProps设置成为第一层接口即可. 比如:

export interface TodoListInnerProps extends RouteComponentProps<{}> {  todos: Todo[];}export interface TodoListProps extends TodoListInnerProps {  className?: string;  onLoad?(): void;}@withRouter@connect((state) => ({ todos: state.todos })export class TodoList extends PureComponent
{ static defaultProps: TodoListInnerProps render() { return null }}

需要注意的是:

  1. TypeScript 要 3.0.1以上
  2. @types/react 要最新版
  3. withRouter, connect 等函数在 @types中, 签名有问题, 需要手动修改一下:

    import { ComponentClass } from 'react'import {  connect as nativeConnect,  MapDispatchToPropsParam,  MapStateToPropsParam} from 'react-redux'import { withRouter as nativeWithRouter } from 'react-router'export type ComponentDecorator

    =

    >(WrappedComponent: T) => Texport const connect:
    ( mapState: MapStateToPropsParam

    , P, S>, mapDispatch?: MapDispatchToPropsParam

    , P>) => ComponentDecorator = nativeConnect as anyexport const withRouter: ComponentDecorator = nativeWithRouter as any

转载地址:http://ypykm.baihongyu.com/

你可能感兴趣的文章
Swift - what's the difference between metatype .Type and .self?
查看>>
Matroid[转]
查看>>
Android 实现歌词同步
查看>>
c#设计模式-观察者模式
查看>>
如何使用cocos2d制作基于tile地图的游戏教程:第一部分
查看>>
SVN的版本日期
查看>>
圆满完成性能测试诊断分析与优化周末班培训课程!
查看>>
C# 通过消息捕获处理窗体最大化/最小化
查看>>
metabase docker-compose 运行说明
查看>>
C# ToShortDateString() ToString() 设置日期格式的区别
查看>>
HDU-1016 Prime Ring Problem DFS
查看>>
MOSS 2007 入门 : 站点定义和站点模板
查看>>
网页性能优化{雅虎[转载]}
查看>>
CentOS6.2下搭建LVS(DR)+Keepalived实现高性能高可用负载均衡
查看>>
强制旋转iPhone界面
查看>>
最近琢磨出了个测试数据的小技巧
查看>>
vector-list-deque(转)
查看>>
linux 设置时间 date命令
查看>>
键盘设备三星在Android上的改进对Developer的影响
查看>>
分区视图(转载)
查看>>