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

        此文章是本人在学习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
                })
            }

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

猜你喜欢

转载自blog.csdn.net/zhangawei123/article/details/130921774