React学习笔记九-高阶函数与函数柯里化

news2024/12/29 9:09:32

        此文章是本人在学习React的时候,写下的学习笔记,在此纪录和分享。此为第九篇,主要介绍高阶函数与函数柯里化。

高阶函数,和函数的柯里化,是学习react的拓展,方便以后优化代码,更好的学习react。

目录

高阶函数

案例

高阶函数定义 

函数的柯里化

函数柯里化的定义

柯里化小案例

不用柯里化的写法


高阶函数

案例

先把上一笔记里面的案例,拿出来:这个案例就是,两个输入框分别是用户名和密码,输入用户名和密码,点击登录按钮,会弹出一个提示框,显示你输入的用户名和密码。

 <!-- 准备好容器 -->
    <div id="test1"></div>
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
    <!-- 新引入的库,用于限定props传入值的类型,propTypes -->
    <script src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>

    <script type="text/babel">
        class Login extends React.Component {
            //状态初始化
            state = {
                username:'',//用户名
                password:''//密码
            }
            //保存用户名到状态中
            saveUsername = (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 action="http://www.atguigu.com" onSubmit={this.handleSubmit}>
                        用户名:<input onChange = {this.saveUsername} type="text" name="username" />
                        密码:<input onChange = {this.savePassword} type="password" name="password" />
                        <button>登录</button>
                    </form>
                )
            }
        }
        ReactDOM.render(<Login />, document.getElementById('test1'))
    </script>

        如代码所示,表单中需要获取用户名和密码,并且加以操作,所以有了对应的两个方法:saveUsername和savePassword。但如果还存在性别,年龄,电话号码等等信息需要操作,是不是得一一对应,写很多方法?实在是过于冗余,有没有什么解决的办法?

        所以我们只写一个方法saveFormData来代替saveUsername和savePassword,来给表单中所有的属性使用:

 用户名:<input onChange = {this.saveFormData("username")} type="text" name="username" />
 密码:<input onChange = {this.saveFormData("password")} type="password" name="password" />
saveFormData = (event)=>{
     this.setState({
          password:event.target.value
     })
}

        但是,这会出现很大的错误。注意onchange的回调函数,它非是一个函数进行了回调,而是一个函数的返回结果进行了回调:this.saveFormData("username"),saveFormData加了小括号,已经在回调时执行完了,产生了函数的返回值,这个返回值参与了回调,就会发生错误。

        必须将一个函数返回给onchange作为回调。

如下的写法,才是onchange事件触发时候,回调saveFormData这个函数。

<input onChange = {this.saveFormData} 

        而且这个saveFromData函数,this.setState也会一直把数据给password。我们接下来修改这些错误。

        那么怎么才能在加()的情况下,也能正确执行回调函数呢。众所周知函数加了()就是执行函数产生返回值,那么我们直接让返回值是一个函数不就行了。

改写这个saveFromData函数:

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

        我们将saveFromData函数的返回值,写成了一个函数。如此一来,onchange事件触发后,回调saveFromData函数的返回值,仍然是一个函数,便能达到正常的效果。

        我们在onChange={this.saveFormData("username")}中传入参数,在saveFromData函数设置形参dataType接收这个参数,在this.setState中以中括号包裹形参(中括号表示其中是是一个变量,不写中括号会当作一个键名),设置state,这样就可以区分数据,在state中分开保存不同的数据。

来看效果:

高阶函数定义 

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

        1.若A函数,接收的参数是一个函数,那么A就可以被称为高阶函数。

        2.若A函数,调用的返回值依然是一个函数,那么A就可以被称为高阶函数。

由此可见:saveFromData函数就是一个高阶函数,调用的返回值是一个函数。

常见的高阶函数,如promise,数组迭代的那几种方法,定时器。

函数的柯里化

函数柯里化的定义

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

柯里化小案例

为了理解柯里化,我们先正常的写一个普通函数的案例:a,b,c 的求和

function sum(a,b,c){
            return a+b+c
        }
        const result = sum(1,2,3)
        console.log(result);

现在把上面的案例,改成柯里化的写法:

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

这个案例里面的函数柯里化,看似把简单的问题复杂化,变得麻烦,又有些回调地狱的风格。但实际应用上,函数柯里化经常使用。比如说第一个案例,里面的saveFromData函数:

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

先接收了参数dataType,然后再接收了event参数,在后面对两个参数统一处理了,这就是函数的柯里化。

不用柯里化的写法

        如果我们不用柯里化的写法,这就要求我们一次性拿到所有参数。主要是在onchange事件里,想办法把两个参数一次性给saveFromData函数传过去。

        给onchange事件回调的,必须是一个函数。我们尝试写一个内联函数,这样既能在内联函数中把参数传递给saveFromData函数,又可以保证是一个函数回调给事件。

如下:onChange={(event)=>{this.saveFormData('username',event.target.value)}}

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

然后我们就可以把saveFromData函数改写成一个普通的函数:

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

如此,我们改写了这两个部分,就可以把柯里化写法,改成普通的函数写法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/592311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c语言编程练习题:7-115 小于m的最大的10个素数

#include <stdio.h> int is_prime(int a){for (int i2;i<a;i){if (a%i0){return 0;}}return 1; }int main(){int n;int count10;if (scanf("%d",&n)!EOF && n>50 && n<20000){// 计算150&#xff0c;分配给5&#xff0c;2&#x…

UOS桌面系统开机进入Busybox

UOS桌面系统开机进入Busybox 一、问题现象二、解决方案1、livecd工具修复a、制作livecd工具盘b、从优盘启动c、磁盘修复 2、使用fsck修复a、找出有问题的分区b、修复分区c、重启电脑 一、问题现象 开机进入如下图所示界面 问题原因&#xff1a;roota分区损坏 二、解决方案 …

MySQL — InnoDB引擎、MySQL架构、事务原理、MVCC

文章目录 InnoDB引擎一、逻辑存储架构二、架构2.1 内存结构2.1.1 Buffer Pool 缓冲池2.1.2 Change Buffer 更改缓冲区2.1.3 Log Buffer 日志缓冲区域2.1.4 Adaptive Hash Index 自适应hash索引 2.2 磁盘结构2.2.1 System Tablespace 系统表空间2.2.2 File-Per-Table Tablespace…

搭建一个vuepress静态网站及配置

搭建一个vuepress静态网站及配置 一、搭建一个vuepress网站1、创建并进入一个新目录2、初始化3、安装依赖4、创建文档5、配置启动命令及启动6、展示效果 二、配置及丰富vuepress网站1、增加配置文件2、配置侧边栏目录3、使用部分markdown语法完善页面 一、搭建一个vuepress网站…

【Python实战】Python采集热榜数据

前言 大家好,我们今天来爬取热搜榜,把其文章名称,链接和作者获取下来,我们保存到本地,我们通过测试,发现其实很简单,我们只要简单获取数据就可以。没有加密的东西。 效果如下: 环境使用 python 3.9pycharm模块使用 requests模块介绍 requests requests是一个很…

​​​​Linux Shell 实现一键部署Ruby3

ruby Ruby&#xff0c;一种简单快捷的面向对象&#xff08;面向对象程序设计&#xff09;脚本语言&#xff0c;在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发&#xff0c;遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp …

【上篇】我们邀请了4位专家来探讨消费市场的新增量:W型机会、单客经济、日本市场、DTC......

好久不见了&#xff0c;我是增长黑盒的创始人yolo。最近我们总是发布一些严肃型的行业报告&#xff0c;相信大家的动作都是在第一时间点个收藏&#xff0c;然后....就没有然后了。 所以&#xff0c;今天我们的内容没有复杂的图表和数据&#xff0c;想用比较轻松的对话形式来呈现…

专业的知识图谱应用门槛正在被不断降低

前⾔ 知识图谱&#xff08;knowledge graph&#xff09;⼀度被专家称为“AI皇冠上的明珠”&#xff0c;因为知识图谱技术是⼈⼯智能技术⽅向中的重要⼀环。它不仅可以为其他⼈⼯智能应⽤提供⽀持&#xff0c;如⾃然语⾔处理、推荐系统等&#xff0c;更可以帮助⼈⼯智能系统⾃主…

小程序开发中常见问题解决技巧

众所周知&#xff0c;开发小程序是一件复杂而又繁琐的事情&#xff0c;而且小程序开发也需要一定的技术含量&#xff0c;同时还需要投入大量的时间和精力。所以&#xff0c;在小程序开发过程中&#xff0c;难免会遇到各种各样的问题。为了让大家可以顺利地开发出高质量的小程序…

物联网网关在预付费售电管理系统的构建及应用

摘 要&#xff1a;在社会的不断发展与进步下&#xff0c;信息产业也迎来了自己的繁荣时代&#xff0c;物联网正是在这样的背景之下进入了人们的视野。在互联网的不断发展以及计算机技术的各种进步之下&#xff0c;物联网也迎来了一个又一个的突破&#xff0c;物联网&#xff0c…

契约锁参与第四届【鼎捷智造节】,携手推进制造业数智化转型

如今&#xff0c;制造业正处在智能制造转变的关键期&#xff0c;各类数字化需求不断涌现&#xff0c;为了推动行业数字化转型&#xff0c;鼎捷软件于2021年10月首发启动【鼎捷智造节】&#xff0c;集生态合作圈打造、企业转型赋能、业内优秀产品服务于一体&#xff0c;汇聚业内…

JS的isNAN:判断数字是否合法

定义和用法 isNaN() 函数用于检查其参数是否是非数字值。 如果参数值为 NaN 或字符串、对象、undefined等非数字值则返回 true, 否则返回 false。 语法 isNaN(value) 参数描述value必需。要检测的值。 <!DOCTYPE html> <html lang"en"> <head><…

百万数据导出,居然爆炸了OutOfMemoryError?

一、问题的提出 /*** 大数据导出1.0* /demo/exportExcel4* param response*/ GetMapping("/exportExcel4") public void exportExcel4(HttpServletResponse response) throws IOException {Date start new Date();// 模拟数据List<UserExportVO> users new …

「从零入门推荐系统」19:HM推荐系统代码实战案例

作者 | gongyouliu 编辑 | gongyouliu 我们在上一章中利用Netflix prize数据集讲解了最基础、最简单的一些推荐系统召回、排序算法&#xff0c;大家应该对怎么基于Python实现推荐算法有了一些基本的了解了。接着上一章的思路&#xff0c;本章我们会基于一个更复杂、更近代一点的…

JAVA企业级开发 1.5 初探Spring AOP

一、提出游吟诗人唱赞歌任务 骑士执行任务前和执行任务后&#xff0c;游吟诗人唱赞歌 &#xff08;一&#xff09;采用传统方式实现 修改day04子包的勇敢骑士类 修改day04子包里的救美骑士类 执行测试类 - TestKnight &#xff08;二&#xff09;采用传统方式实现的缺…

Hive部署本地模式

本地模式 使用mysql替换derby进行元数据的存储&#xff0c;hive的相关进程都是在同一台机器上&#xff0c;即本地模式。mysql因为是独立的进程&#xff0c;所以mysql可以和hive在同一机器上&#xff0c;也可以在其他机器上。 说明&#xff1a; 通常使用关系型数据库来进行元数据…

微信公众号、支付接口认证:一步步教您如何实现

1、微信公众号接口认证方案 1.1 认证流程 1&#xff09;官方配置Token验证 Token不在网络中传递 2&#xff09;开发一个Token验证接口 Token及其它参数拼接并字典排序再做sha摘要计算微信定期调用此接口来验证身份正确性通过摘要验证判断请求来源微信&#xff08;Token配置…

TensorFlow进行MNIST数据集手写数字识别,保存模型并且进行外部手写图片测试

首先&#xff0c;你已经配置好Anaconda3的环境&#xff0c;下载了TensorFlow模块&#xff0c;并且会使用jupyter了&#xff0c;那么接下来就是MNIST实验步骤。 数据集官网下载&#xff1a;MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burgeshttp…

apple pencil的替代品买啥比较好?平价电容笔推荐

随着技术的发展&#xff0c;出现了许多种类的电容笔。一款好的电容笔&#xff0c;不但可以极大地提升我们的工作效率&#xff0c;也可以极大地改善我们的学习效果。平替电容笔无论是在技术方面&#xff0c;还是在产品质量方面&#xff0c;都有着非常广泛的应用前景。下面就是我…

Java领域的序列化与反序列化,Java的对象如何传输,常用序列化技术

文章目录 一、引出问题&#xff1a;Java原生的序列化1、基于Socket传输对象案例2、什么是序列化3、Java 原生序列化4、serialVersionUID 的作用5、transient 关键字绕开 transient 机制的办法writeObject 和 readObject 原理 6、Java 序列化的一些简单总结 二、分布式架构下常见…