美文网首页
react中装饰器的使用

react中装饰器的使用

作者: 凉生可可 | 来源:发表于2018-12-17 15:01 被阅读0次

    利用装饰器简化代码,将表单验证操作统一到一个装饰器中进行

    首先装饰器的定义为修饰器(Decorator)是一个函数,用来修改类的行为。
    建立一个装饰器

    export default (Comp) => {
       class Cp extends Comp{
         constructor(props){
                super(props);
                this.state = {
                    ...this.state,
                    errors: {
    
                    },     
                     // error queuq
                this.errorQueue = {};
                }
                this.setEmailcode = this.setEmailcode.bind(this);
                 this.callError = this.callError.bind(this);
                this.fIn = this.fIn.bind(this);
                this.bOut = this.bOut.bind(this);
                    
        }
         setEmailcode(v){
                this._clearStateKey('emailcode', v);
                if(v.target.value.length < 7){
                    this._changeHandler('emailcode', v);
                }
            }
            ckemailcode(){
            let rt = true;
                 const errors = [];
                 const KEY = 'gcode';
                    const intl = this.intl
    
                this._isEmpty(this.state[KEY], errors, intl.formatMessage({id: "请输入谷歌验证码"}));
                //验证是否符合规则,不符合则扔到errors队列中去
                this._setError(KEY, errors);
            
                return this._hasError(KEY); 
            }
         _isEmpty(v, errors = [], msg = ''){
                !v && errors.push(msg);
                return !v;
            }
            _changeHandler(k, v){
                const target = v.target;
                const value = target.type === 'checkbox' ? target.checked : target.value;
                this.setState({
                    [k]: value
                });
            }
             // flg is get code 1 is get code
            _setError(k, v, flg = 0){
                let { errors } = this.state,
                cd = this._isArray(v) && v.length;
           
                !this.errorQueue[k] && (this.errorQueue[k] = []);
    
                this.errorQueue[k][flg] = cd ? v : [];
                setTimeout(() => {
                    this.setState(prevState => {
                        return {
                            errors: {
                                ...(prevState.errors),
                                [k]: cd ? (
                                    errors[k] ? errors[k].unshift(...v) : errors[k] = [...v],
                                    [...new Set(errors[k])]
                                ) : [...(this.errorQueue[k].filter(v => {
                                    return v.length > 0;
                                })[0] || [])],
                            }
                        }
                    });
                },0);
            }
            _hasError(k = ''){
               return !this.errorQueue[k].filter(v => v.length > 0).length;
            }
            callError(k, v){
                this._setError(k, v?[v]:[], 1);
                // keydown
                const KEY = 'ky' + k;
                if(this.state[KEY]){
                    this.setState({
                        [KEY]: 0
                    });
                }
            }
    
            clearsError(k = [], flg = 0){
                k.forEach(v => {
                    this._setError(v, "",flg);
                });
                return new Promise((r,e) => {
                    setTimeout(() => {
                        r(1);
                    })
                })
            }
            
            changeImgCode() {
                let now = +new Date;
                this.props.changeImgCode(URL_IMG_CODE + "?t=" + now);
            }
            bOut(e){ 
                const k = this._getTgKey(e);
               if(this.state.focusBlu){
                    this.setState({
                        focusBlu:''
                    })
                }
               
                this.clearQueueKey(k);
                this.hasError([k]);
                this.Uc(k);
            }
             fIn(e){
                const key = this._getTgKey(e);
                key === 'password' && this.setState({
                    mvInPwd: 1
                })
                this._setError(key, []);
                this._setError(key, [], 1);
            }
    
            _isEmpty(v, errors = [], msg = ''){
                !v && errors.push(msg);
                return !v;
            }
         return Cp;
    }
    

    在需要做表单验证的地方引入装饰器

    import Form from '../../../decorator/form';
    @Form
    class WithdrawForm extends React.Component{
    constructor(props){
            super(props)
            this.state = {
            emailcode : "",
    }
    this.setFoucs = this.setFoucs.bind(this)
    
    }
     setFoucs(name){
        this.setState({
            focusBlu:name
        })
       }
    renner(){
    const {setEmailcode,bOut,fIn} = this
    const {errors,ckFlg,emailcode} = this.state
    const {emailcode:eemailcode = [] } = errors
    return(
    <div>
        <div className={`${ckFlg && eemailcode[0] && 'err'} input_div_1 input_div_2`} style={{borderColor:focusBlu=='emailcode'?'#6687D3':''}}>
         <input type="text" className="input_1 input_2"  placeholder={formatMessage({id: "请输入邮箱验证码(水印)"})} onPaste={setEmailcode} autoComplete="off" value={emailcode} onChange={setEmailcode} name="emailcode"  onFocus={(e)=>{this.setCk();this.setFoucs('emailcode');this.fIn(e)}} onBlur={bOut} />
         </div>
         <span className="ew">{ckFlg ? eemailcode[0] : null}</span>//错误提示信息
    </div>
    )
    }
    export default WithdrawForm
    

    相关文章

      网友评论

          本文标题:react中装饰器的使用

          本文链接:https://www.haomeiwen.com/subject/qgdqkqtx.html