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映射为可选的,因为它们在组件实现中是不可选的。



TypeScript 3.0下react默认属性DefaultProps解决方案的更多相关文章
- IE10-IE11在NET4.0下出现“__doPostBack未定义”解决方案
IE10在NET4.0下出现"__doPostBack未定义"的办法 参考文章: http://blogs.msdn.com/b/scott_hanselman/archive/2 ...
- React 学习(二) ---- props验证与默认属性
在上一节中, 我们提到了props, 组件之间数据的传递使用props. 我们调用组件时可以设置props, 组件内部通过props获取. 为了props 使用更加友好, React 提供了简单的验证 ...
- 关于div容器在ie6下默认高度不为0(存在默认高度)
最近做项目的时候遇到一个问题,相信很多人都遇到过,就是在测试兼容性的时候,在ie6下小于12px 的背景的高度不等于原高,或许这样说你可能不是很明白,那就举个例子吧! 如图所示: 锯齿状的背景图本来是 ...
- CDH 6.0.1 版本 默认配置下 HUE | happybase 无法访问 Hbase 的问题
第一个问题 HUE 无法直接连接到 HBase 在默认配置下 CDH 6.0.1 版本下的 HBase2.0 使用了默认配置 hbase.regionserver.thrift.compact = T ...
- React组件属性部类(propTypes)校验
React组件属性类型(propTypes)校验 Prop 验证 随着应用不断变大,保证组件被正确使用变得非常有用.为此我们引入propTypes.React.PropTypes 提供很多验证器 (v ...
- 在 Typescript 2.0 中使用 @types 类型定义
在 Typescript 2.0 中使用 @type 类型定义 基于 Typescript 开发的时候,很麻烦的一个问题就是类型定义.导致在编译的时候,经常会看到一连串的找不到类型的提示.解决的方式经 ...
- Vue.js 2.0 和 React、Augular
Vue.js 2.0 和 React.Augular 引言 这个页面无疑是最难编写的,但也是非常重要的.或许你遇到了一些问题并且先前用其他的框架解决了.来这里的目的是看看Vue是否有更好的解决方案.那 ...
- 使用Typescript重构axios(十五)——默认配置
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- TypeScript 2.0开启空值的严格检查
摘要:在编程过程成空指针是最常见的bug之一,但是在TypeScript中我们无法使用具体的类型来表示特定的变量不能为空!幸运的是,TypeScript 2.0 解决了这个问题. 本文分享自华为云社区 ...
随机推荐
- 一篇RxJava友好的文章(二)
上一篇文章介绍了rxjava的基本用法,和一些常用的操作符,以及rxjava的链式操作带来的好处.由于rxjava非常的强大,让我如此的痴迷,我打算写五篇文章,专门讲解rxjava 常见的操作符和用法 ...
- SVProgressHUD–比MBProgressHUD更好用的 iOS进度提示组件
简介 SVProgressHUD是简单易用的显示器,用于指示一个持续进行的任务的进度. 项目主页: SVProgressHUD 最新示例: 点击下载 快速入门 安装 通过Cocoapods pod ' ...
- mysql 1055 的错误
1.Err1055,出现这个问题往往是在执行sql语句时候,在最后一行会出现这个问题. [Err] 1055 - Expression #1 of ORDER BY clause is not in ...
- CentOS7密码忘记解决方法&&GRUB菜单加密
CentOS7的root密码忘记怎么办 注意:该方法只适用于Linux7版本,可以用cat /redhat-release 查看 这里这里只介绍一种方法 1.启动的时候,在启动界面,相应启动项,内核名 ...
- Java OOP——第八章 File IO
1.文件:文件可认为是相关记录或放在一起的数据的集合: 2.File类:名命空间:java.io File对象即可表示文件,也可表示目录, 在程序中,一个File对象可以代表一个文件或目录, 利用他可 ...
- Delphi中DLL的创建和使用(转)
Delphi中DLL的创建和使用 1.DLL简介: 2.调用DLL: 3.创建DLL: 4.两个技巧: 5.初始化: 6.例外处理. 1.DLL简介 ...
- 45.VUE学习之--组件之父组件使用scope定义子组件模板样式结构实例讲解
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- php实现当前页面点击下载文件的实例
php控制器中代码 public function downFile($path = ''){ if(!$path) header("Location: /"); ...
- Spark提交任务(Standalone和Yarn)
Spark Standalone模式提交任务 Cluster模式: ./spark-submit \--master spark://node01:7077 \--deploy-mode clus ...
- [BZOJ3714]Kuglarz(最小生成树)
Description 魔术师的桌子上有n个杯子排成一行,编号为1,2,-,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品.花费\(C_{i,j}\)元,魔术师就会告诉 ...