react 中的高阶函数和柯里化

这一篇博文我们说一下 高阶函数 和 柯里化,这两个次可能第一次听说,不知道是啥意思,我们先不管他哈,记得上一篇博客,我们实现了一个登陆的案例是吧?输入用户名和密码,点击登陆按钮,弹出用户名和密码输入的问题,我们跟随着这个案例来思考一些问题。

上篇博客案例

代码:

    <!-- 此处必须写 text/babel --><script type="text/babel">// 创建组件class Login extends React.Component {state = { username: '', password: '' }handleSubmit = (event) => {event.preventDefault()  // 阻止默认事件,即表单提交组织const { username, password } = this.statealert(`你输入的账号是 ${username},你输入的密码是 ${password}`)}saveUsername = (event) => {this.setState({ username: event.target.value })}savePassword = (event) => {this.setState({ password: event.target.value })}render() {return (<form onSubmit={this.handleSubmit}>账号:<input onChange={this.saveUsername} type="text" name="username" /> <br />密码:<input onChange={this.savePassword} type="passwofd" name="password" /><br /><button>登 录</button></form>)}}// 渲染组件ReactDOM.render(<Login />, document.getElementById("app"))</script>

效果:

高阶函数

我们看上面的代码哈,我们在保存账号密码的时候呢,写了两个含糊,在输入框改变的时候分别调用的这两个函数,但是我们观察这两个函数:

         // 保存账号到状态saveUsername = (event) => {this.setState({ username: event.target.value })}// 保存密码到状态savePassword = (event) => {this.setState({ password: event.target.value })}

有没有觉得这两个方法高度相似?这是只保存密码和账号,如果业务比较大,比如注册,需要保存用户名、密码、确认密码、邮箱、电话、性别、地址… 这样的话会异常的繁琐,代码会特别的冗余。有没有什么好的办法解决呢?

比如我们就写一个方法,根据传进的参数确定保存的是啥,怎么修改?

那在输入框的change事件里面,就需要修改一下吧

账号:<input onChange={this.saveFormData('username')} type="text" name="username" /> <br />
密码:<input onChange={this.saveFormData('password')} type="passwofd" name="password" /><br />

这样改吧?都用 saveFormData 方法,根据传进的是 username 还是 password 来判断保存的是啥。

那我们得写一个 saveFormData 方法吧?那写一个,这样的话,之前的两个保存方法就可以舍弃了。

// 保存表单数据到状态中
saveFormData =(dataType) =>{console.log(dataType)
}

dataType 就是我们传进的 username 或者是 password 吧?这样是有问题的,什么问题呢?之前博客点击事件的时候我们说过,onChange={ } 这个花括号里面需要写 js 表达式,如果我们给方法加上 () 了的话,他会被直接执行对吧?

我们直接刷新看一下效果:


我们看到哈,一刷新页面,控制台直接打印了是吧?这个是肯定的原因也说了。然后我在输入框输入数据之后,onChange 事件就不执行了,这是为啥?其实也好理解,因为 onChange 接受的是 { } 里面 js 表达式返回的值吧?但是这个 saveFormData 函数有返回值吗?没有!所以是 undefined。onChange 赋值了个 undefined,所以不会被触发,就相当于没有用。就是这个原因。

怎么解决呢?思考一下。

既然 onChange 需要的是一个方法,那就给他一个方法。

            // 保存表单数据到状态中saveFormData =(dataType) =>{return () => {}}

这样就可以啦吧!那你说,onChange 最后回调的是 saveFormData ,还是 saveFormData 里面返回的箭头函数

很显然是saveFormData 里面返回的箭头函数啊!

所以说 返回的箭头函数可以获取到 event 吧?不确定就打印一下,同时我们把 dataType 也打印一下。

            // 保存表单数据到状态中saveFormData = (dataType) => {return (event) => {console.log(dataType, event.target.value)}}

保存看效果:


哎哟,这不就都拿到了嘛,保存的是啥,值是啥,都拿到了。接下来就是简单的保存进状态了。

怎么保存进状态,很多宝子很聪明,是这样写的。

            // 保存表单数据到状态中saveFormData = (dataType) => {return (event) => {this.setState({ dataType: event.target.value })}}

额~ 这样肯定是不可以的哈!


你看截图,如果这样写了的话,保存起来之后,既没有改变 username,也没有改变 password,而是创建了新的 dataType 保存了。那正确的保存方式怎么写呢?

            // 保存表单数据到状态中saveFormData = (dataType) => {return (event) => {this.setState({ [dataType]: event.target.value })}}

这样子就可以啦哈


为什么这样写,我说一下吧。首先我们回顾一下 对象的相关知识。

对象的相关知识

假设我有一个变量 a 的值是 name,有一个空对象 obj,我想把 obj 变成 { name: "我是ed." } 怎么做?

    <script>let a = "name"let obj = {}  // {name: '我是ed.'}obj.name = '我是ed.'console.log(obj)</script>

上面代码是没有问题的吧?

当然没问题,但是 a 没有用到啊,如果要用 a 呢?

        obj[a] = '我是ed.'console.log(obj)

这样子就可以了吧?所以说

this.setState({ [dataType]: event.target.value })

这个地方的 dataType 加上中括号就可以了。

好的,这样保存状态尽管在两个地方需要,但是只需要一个函数就可以实现了!

    <!-- 此处必须写 text/babel --><script type="text/babel">// 创建组件class Login extends React.Component {state = { username: '', password: '' }handleSubmit = (event) => {event.preventDefault()  // 阻止默认事件,即表单提交组织const { username, password } = this.statealert(`你输入的账号是 ${username},你输入的密码是 ${password}`)}// 保存表单数据到状态中saveFormData = (dataType) => {return (event) => {this.setState({ [dataType]: event.target.value })}}render() {return (<form action="http://www.baidu.com" onSubmit={this.handleSubmit}>账号:<input onChange={this.saveFormData('username')} type="text" name="username" /> <br />密码:<input onChange={this.saveFormData('password')} type="passwofd" name="password" /><br /><button>登 录</button></form>)}}// 渲染组件ReactDOM.render(<Login />, document.getElementById("app"))</script>

效果很完美


案例我们改造完了,那我们改造的 saveFormData 函数就是高阶函数

         // 保存表单数据到状态中saveFormData = (dataType) => {return (event) => {this.setState({ [dataType]: event.target.value })}}

我们看一下高阶函数的定义

高阶函数:如果一个函数不符合下面两个规范中的任意一个,那该海曙就是高阶函数。

  • 若A函数,接受的参数是一个函数,那个A就可以称之为高阶函数。
  • 若A函数,调用的返回值依然是一个函数,那A就可以称之为高阶函数。

常见的高阶函数:Promise、setTimeout、arr.map() 等等。

saveFormData 是根据第二条来定义的,同时这个函数使用了 函数柯里化

什么是函数的柯里化呢?

函数的柯里化:通过函数调用继续返回函数的方式,实现多次接受参数最后统一处理的函数编码形式。

这个函数柯里化不好定义哈,我们看一个例子,一个典型的函数柯里化的例子,数字求和:

    <script>function sum(a) {return (b) => {return (c) => {return a + b + c}}}const result = sum(1)(2)(3)console.log(result)</script>

执行结果出来了,很正确!


如果单纯看这个例子的话,觉得这个求和的例子简直是有病!

但是我们这个登陆的案例,不就是一个很合理的柯里化应用场景吗?我想直接穿一个参数告诉存储方法我要存的是啥,我也想告诉这个存储方法我存储的值是多少,但是 存储的是什么我可以告诉他,但是值是多少也就是 event 是多少,我告诉不了,因为 event 是 react 是回调的时候自动生成出来的,我们不能干涉,所以就是用函数的柯里化解决问题。

OK,今天这部分的内容就到这里了。辛苦了。

【本部分相关代码资料】:我是

16、react 中的高阶函数和柯里化相关推荐

  1. [转载] 高阶函数和柯里化

    参考链接: Python中的First Class函数 高阶函数 一等公民 函数在Python是一等公民(First-Class Object)函数也是对象,是可调用对象函数可以作为普通变量,也可以作 ...

  2. js 高阶函数之柯里化

    博客地址:https://ainyi.com/74 定义 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且 ...

  3. React 中的高阶组件及其应用场景

    本文目录 什么是高阶组件 React 中的高阶组件 属性代理(Props Proxy) 反向继承(Inheritance Inversion) 高阶组件存在的问题 高阶组件的约定 高阶组件的应用场景 ...

  4. python中的高阶函数

    python中的高阶函数 文章目录: 1 什么是高阶函数? 1.1 高阶函数:一个函数的`函数名`作为参数传给另外一个函数 1.2 高阶函数:一个函数返回值(return)为另外一个`函数` 2 py ...

  5. React中的高阶组件

    React中的高阶组件 高阶组件HOC即Higher Order Component是React中用于复用组件逻辑的一种高级技巧,HOC自身不是React API的一部分,它是一种基于React的组合 ...

  6. 【Kotlin】Kotlin 语言集合中的高阶函数详解 ( 数据类 data class | maxBy | minBy | filter | map | any | count | find )

    文章目录 I . List 集合高阶函数引入 II . Kotlin 数据类 ( data class ) III . Java 代码 与 Kotlin 代码实现对比 ( 查询年龄最大的 ) IV . ...

  7. 1 access中iif函数中的_JavaScript中的高阶函数

    前言 在 JavaScript 的学习过程中,我们可能或多或少地接触过高阶函数.那么,我们自己对此是否有一个明确的定义,或者说很熟练的掌握这些用法呢 如果文章中有出现纰漏.错误之处,还请看到的小伙伴多 ...

  8. Kotlin中的高阶函数

    博客地址sguotao.top/Kotlin-2018- 在Kotlin中,高阶函数是指将一个函数作为另一个函数的参数或者返回值.如果用f(x).g(x)用来表示两个函数,那么高阶函数可以表示为f(g ...

  9. scala中的高阶函数_Scala中的高阶函数(HOF)

    scala中的高阶函数 Higher Order Functions (HOF) in Scala are the very core of this functional programming l ...

最新文章

  1. CSS中的字体属性和使用
  2. hive报错(1)MoveTask/HIVE return code 1、2、3
  3. Netlib文件转化为mps文件
  4. C# Excel数据有效性
  5. 设置上传文件的最大大小
  6. 如何启用计算机超级账户,Windows7启用超级管理员账户的方法
  7. Oracle_Rac_BackgroudProcess
  8. 为什么说Java是2021年最值得学的技术?
  9. 用开源NAC阻止非法网络访问
  10. 琥珀项目:较小的,面向生产力的Java语言功能
  11. javascript练习----复选框全选,全不选,反选
  12. lnmp mysql 远程访问_LNMP环境下 远程连接mysql数据库
  13. 【转】我应该直接学Swift还是Objective-C?
  14. 阿里云 POSTFIX 邮件服务 PHP
  15. java生成图表_【JAVA】POI生成EXCEL图表(柱状图、折线等)
  16. 2018 Google IO大会来了
  17. PNG-的IDAT解析
  18. python输入名字配对情侣网名_名字匹配情侣网名
  19. 天天向上答案python_天天向上的力量python(举一反三)
  20. CMake中使用get_target_property判断Target是否存在

热门文章

  1. 浅谈社群运营的2种抽奖玩法
  2. 测试qq和微信voip内网穿透
  3. Python语言程序设计——实验八
  4. 未来计算机 教学反思,计算机基础教学反思.doc
  5. 宝塔面板网页访问不了
  6. 台式机电源相关参数说明
  7. 高效办公!Python 批量生成PDF文档
  8. 基于云服务器 B/S模式 JavaWeb RFID 图书借阅管理系统
  9. 服装商城网站 毕业设计-附源码241505
  10. 腾讯地图、高德地图去除logo方法