zoukankan      html  css  js  c++  java
  • 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”
    image

    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>
    }
    
    

    说明

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

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

    image
    image
    image

  • 相关阅读:
    Herny
    机器学习No.4
    机器学习No.3
    机器学习No.2
    机器学习No.1
    算法第五章上机实践报告
    算法第五章作业
    算法第四章实践报告
    算法第四章作业
    算法第三章作业
  • 原文地址:https://www.cnblogs.com/chenjinxinlove/p/9706299.html
Copyright © 2011-2022 走看看