(代码优化)高阶函数与函数柯里化

108 阅读1分钟

原来:

class Login extends React.Component{
    //初始化状态
    state = {
        username:'', 
        password:'' 
    }
    saveUsername = (event)=>{
    //没有传参时,event为事件对象
        this.setState({username:event.target.value})
    }
    savePassword = (event)=>{
        this.setState({password:event.target.value})
    }
    handleSubmit = (event)=>{
        event.preventDefault() //阻止表单提交
        const {username,password} = this.state
        alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
    }
    render(){
        return(
            <form onSubmit={this.handleSubmit}>
                用户名:<input onChange={this.saveUsername} type="text" name="username"/>
                密码:<input onChange={this.savePassword} type="password" name="password"/>
                <button>登录</button>
            </form>
        )
    }
}

<input onChange={this.saveUsername}:把saveUsername这个函数交onchange作为回调,DOM有变化时就会调用

优化一:使用高阶函数与函数柯里化

saveFormData = (dataType)=>{
    return (event)=>{
        this.setState({[dataType]:event.target.value})
    }
}

//把saveFormData的返回值(是个函数)交给onchange作为回调,所以当DOM有变化时,会不断调用这个返回值函数
用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>

高阶函数:

符合下面2个规范中的任何一个的函数:

  • 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。如Promise、setTimeout、数组身上一些常见的方法(比如arr.map()
  • 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数

函数的柯里化:

通过函数调用继续返回函数的方式,实现多次接收参数后统一处理的函数编码形式

/* function sum(a,b,c){
	return a+b+c
} */

function sum(a){
	return(b)=>{
		return (c)=>{
			return a+b+c
		}
	}
}
const result = sum(1)(2)(3)

注意:

不把saveFormData写成

saveFormData = (dataType)=>{
    this.setState({[dataType]:event.target.value})
    
    //不能写成 this.setState({dataType:event.target.value}) 会在state里新增一个名为dataType的key:
    /*因为
    let a = 'name'

    let obj = {}
    obj[a] = 'tom'
    console.log(obj); // {name:'tom'}
    */
}

的原因:

<input onChange={this.saveFormData('username')}:是把saveFormData的返回值作为onchange的回调,这样为undefined。但是必须把函数给onchange作为回调

优化二(推荐)

saveFormData = (dataType,event)=>{
        this.setState({[dataType]:event.target.value})
}

用户名:<input onChange={event => this.saveFormData('username',event) } type="text" name="username"/>