TypeScript 3.0下react默认属性DefaultProps解决方案

ts和react的默认属性的四种解决方案

  • Non-null assertion operator(非空断言语句)
  • Component type casting(组件类型重置)
  • High order function for defining defaultProps(高阶组件)
  • Props getter function(Getter函数)

1、 非空断言语句

1、const color = this.props.color!;
2、this.props.onBlur ? this.props.onBlur(e): undefined;

2、组件类型重置

以通过匿名类创建组件,并将其分配给常量,我们将使用适当的道具类型将其转换为最终结果组件,同时保留实现中定义的所有“defaultProps”

3、高阶组件

globals.d.ts

declare type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

在uitls中定义withDefaultProps

export const withDefaultProps = <P extends object, DP extends Partial<P> = Partial<P>>(
  defaultProps: DP,
  Cmp: React.ComponentType<P>
) => {
  type RequiredProps = Omit<P, keyof DP>
  type Props = Partial<DP> & RequiredProps
  Cmp.defaultProps = defaultProps
  return (Cmp as React.ComponentType<any>) as React.ComponentType<Props>
}

说明

==使用上面或者下面的实现都可以==

input组件为一个完整的例子:

import classnames from ‘classnames‘;
import * as React from ‘react‘;
import { withDefaultProps } from ‘../utils‘;
import ‘./style/input.styl‘;

const defaultProps = {
  type: ‘text‘,
  value: ‘‘,
  disabled: false,
  readonly: false,
  maxlength: 60,
  placehololder: ‘‘,
  autofocus: false,
  autocomplete: ‘‘,
  clearable: false,
  passShow: false
}

type DefaultProps = Readonly<typeof defaultProps>;

type InputInnerProps = {
  prepend?: React.ReactNode;
  append?: React.ReactNode;
  className?: string;
  style?: React.CSSProperties;
  onChange?: (value: string) => void;
  onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
  onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
} & DefaultProps;

const InputState = {
  isFocus: false,
  inputValue: ‘‘,
  open: false
};

type State = Readonly<typeof InputState>;

const Input = withDefaultProps(
  defaultProps,
  class extends React.Component<InputInnerProps, State> {
    readonly state: State = InputState;
    private inputRef: React.RefObject<any> = React.createRef();
    getDerivedStateFromProps() {
      this.setState({
        open: this.props.passShow,
        inputValue: this.props.value
      })
    }

    private changeHander = (e: React.ChangeEvent<HTMLInputElement>):void => {
      this.setState({
        inputValue: e.target.value
      })
      this.props.onChange ? this.props.onChange(e.target.value) : undefined;
    }
    private handleFoucus = (e: React.FocusEvent<HTMLInputElement>):void => {
      this.props.onFocus ? this.props.onFocus(e): undefined;
      this.setState({
        isFocus: true
      })
    }
    private handleBlur = (e: React.FocusEvent<HTMLInputElement>):void => {
      this.props.onBlur ? this.props.onBlur(e): undefined;
      this.setState({
        isFocus: true
      })
    }
    private handleClear = ():void => {
      this.setState({
        inputValue: ‘‘
      })
      this.inputRef.current.focus();
    }
    private handlePwdEye = ():void => {
      this.setState({
        open: !this.state.open
      })
    }
    public render() {
      const {
        type,
        disabled,
        readonly,
        autocomplete,
        autofocus,
        clearable,
        passShow,
        className,
        style,
        prepend,
        append,
        ...restProps
      } = this.props;
      const {
        isFocus,
        inputValue,
        open
      } = this.state;
      const inputCls = classnames(‘afo-input‘, className, {
        ‘afo-input--active‘: isFocus
      })
      const inputType:string = type === ‘password‘ && passShow ? ‘text‘: type;
      const showClear:boolean = clearable && inputValue && !readonly && !disabled ? true: false;
      const showPwdEye:boolean = type === ‘password‘ && passShow && !disabled ? true: false;
      return (
        <div className={inputCls} style={style}>
          {
            prepend ? <div className="afo-input__prepend">{prepend}</div> : ‘‘
          }
          <input
            className="afo-input__field"
            ref={this.inputRef}
            value={inputValue}
            {...restProps}
            type={inputType}
            disabled={disabled}
            readOnly={readonly}

            autoComplete={autocomplete}
            autoFocus={autofocus}
            onFocus={(e) => this.handleFoucus(e)}
            onBlur={(e) => this.handleBlur(e)}
            onChange={(e) => this.changeHander(e)}
          />
          {
            append || showClear || showPwdEye?
            <div className="afo-input__append">
              {
                showClear ? <div className="afo-input__clear"  onClick={() => this.handleClear()}>
                  <i className="afo-wrong" />
                </div> : ‘‘
              }
              {
                showPwdEye ?
                <div className="afo-input__eye"  onClick={() => this.handlePwdEye()}>
                  <i className={open ? ‘afo-inupt__eye--visible‘ : ‘afo-inupt__eye--invisible‘} />
                </div> : ‘‘
              }
              {append}
            </div> :‘‘
          }
        </div>
      )
    }
  }
)

export default Input;

4、Props getter function

条件类型映射的简陋工厂/闭包标识函数模式。

注意,我们使用了与withDefaultProps函数类似的类型映射构造,但我们不将defaultProps映射为可选的,因为它们在组件实现中是不可选的。

原文地址:https://www.cnblogs.com/chenjinxinlove/p/9706299.html

时间: 2024-10-15 18:39:47

TypeScript 3.0下react默认属性DefaultProps解决方案的相关文章

IE10-IE11在NET4.0下出现“__doPostBack未定义”解决方案

IE10在NET4.0下出现"__doPostBack未定义"的办法 参考文章: http://blogs.msdn.com/b/scott_hanselman/archive/2011/10/28/asp-net-ie10-dopostback-javascript-ff5.aspx 方法一.浏览器设置成兼容模式. 方法二.安装服务器版的.Net40的补丁. http://pan.baidu.com/s/1hqnCQ7U 包括适用于x86和x64 方法三.点击VisualSutdio

在 Typescript 2.0 中使用 @types 类型定义

在 Typescript 2.0 中使用 @type 类型定义 基于 Typescript 开发的时候,很麻烦的一个问题就是类型定义.导致在编译的时候,经常会看到一连串的找不到类型的提示.解决的方式经过了许多的变化,从 DefinitelyTyped 到 typings.最后是 @types.在 Typescript 2.0 之后,推荐使用 @types 方式. DefinitelyTyped 这个工具已经不被推荐,仅作介绍. 多数来自 javascript 的库是没有 TypeScript 类

React组件属性部类(propTypes)校验

React组件属性类型(propTypes)校验 Prop 验证 随着应用不断变大,保证组件被正确使用变得非常有用.为此我们引入propTypes.React.PropTypes 提供很多验证器 (validator) 来验证传入数据的有效性.当向 props 传入无效数据时,JavaScript 控制台会抛出警告.注意为了性能考虑,只在开发环境验证 propTypes.下面用例子来说明不同验证器的区别: React.createClass({ propTypes: { // 可以声明 prop

FLV视频在IIS6.0下不能播放 处理的方法

FLV视频在IIS6.0下不能播放 Flash视频由于其较高的压缩率和优越的下载速度,前景普遍看好,同时也为Flash课件增色不少.然而,在FLV视频播放中,却有两个头痛的问题    一.FLV视频在IIS 6.0中不能调用问题  早期版本的 IIS 不需要对 Flash 视频流做任何修改.在 Windows 2003 附带的默认 Web 服务器 IIS 6.0 中,服务器需要借助 MIME 类型来确认 FLV 文件为流媒体.   解决办法大致有三种:   1.修改服务器.既然Web服务器上没有

mac 下 react Native android环境搭建

1.参考  上一篇的博客文章 "mac 下 react Native ios环境搭建",前面几步都是必须的,只是,原生客户端不一致 2.Android Studio的安装 A:安装JAVA的SDK 注意:Android Studio需要Java Development Kit [JDK] 1.8或更高版本.你可以在命令行中输入 javac -version来查看你当前安装的JDK版本.如果版本不合要求,可以到 官网上下载 B:除非特别注明,请不要改动安装过程中的选项.比如Android

cocos2d 2.x在opengl es 2.0 下自定义着色器来创建特别酷的特效(译)

cocos2d 2.x在opengl es 2.0 下自定义着色器来创建特别酷的特效(译) (2012-12-24 13:22:17) 转载▼ 标签: it cocos2d opengl 着色器 渲染 翻译:弹涂鱼 PS:欢迎加入开发群:285275050 本文翻译自:http://www.raywenderlich.com/10862/how-to-create-cool-effects-with-custom-shaders-in-opengl-es-2-0-and-cocos2d-2-x#

Html标签的css默认属性值

HTML标签CSS默认属性值大全 如果设置了 *{margin:0;padding:0;},当需要使用边距的时候,就需要还原HTML默认CSS值了. 除了inline和block的定义,主要是要注意body|h1~h6|blockquote|menu|ul|ol|dd等标签的默认样式(margin和font-size). html, address,blockquote,body, dd, div,dl, dt, fieldset, form,frame, frameset,h1, h2, h3

wince 6.0下UDP通信需要注意MAC地址

最近在wince6.0下进行网络通信,在ARM下使用UDP通信协议.当然了,首先按照自己的使用配置wince中的IP,修改注册表即可. 我是wince的菜鸟,但是绝不是使用UDP通信的新手,在windows下跑过多次的UDP发送端和接收端,在wince下却怎么都不能像在windows下使用那么顺利,出现了不可理解的现象: (1)wince和wince相互通信,发送成功了,可是接收端却没有收到数据包: (2)wince和windows相互通信,发送和接收都正常: (3)wince和windows互

【CNMP系列】CentOS7.0下安装Nginx服务

话步前言,CNMP之路,系统起步:http://www.cnblogs.com/riverdubu/p/6425028.html 这回我来讲解下CentOS7.0下如何安装和配置Nginx服务 Nginx的历史不在此赘述,轻量,快是它的特性.只是因为现在的模块没有达到apache的模块数量级,未来有超越apache的势头. 首先,我们要安装个必要的软件(上节提到过,可能有人并未安装) #yum install wget 因为Nginx以来与gcc的编译环境,所以,在mini centos中需要安