【react】高阶函数_函数柯里化

高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数
 1. 若A函数,接受的参数是一个函数,那么A就可以称之为高阶函数
 2. 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数
 常见的高阶函数有:
   Promise  new Promise((resolve, reject) => {})
   setTimeout  setTimeout(() => {}, 2000)
   数组身上的一些方法  例如:arr.map()

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

react是单向的,他没有vue的双向绑定

可输入的表单标签,如果想实现vue那样的双向绑定:有两种方法

  • 数据修改页面实时更新,就需要使用onChange事件和setState去改变数据的状态
class Demo extends React.Component {
     state = {
       username: '',
       password: ''
     }
     handleSubmit = (event) => {
       event.preventDefault()
     }
     saveUsername = (event) => {
       this.setState({ username: event.target.value })
     }
     savePaasword = (event) => {
       this.setState({ paasword: event.target.value })
     }
     render() {
       return (
         <form onSubmit={ this.handleSubmit }>
           用户名:<input type="text" name="username" onChange={ this.saveUsername } />
          密码:<input type="paasword" name="paasword" onChange={ this.savePaasword } />  
           <button>登录</button>
         </form>
       )
     }
}
ReactDOM.render(<Demo />, document.getElementById('test'))

但是如果可输入的表单标签很多,每个标签都要写个onChange事件,就很麻烦,代码也很冗余

  • 给onChange绑定同一个事件,传一个参数,用来区别当前是哪个输入标签;
class Demo extends React.Component {
      render() {
        return (
          <form onSubmit={ this.handleSubmit }>
            用户名:<input type="text" name="username" onChange={ this.saveFormData('username') } />
            密码:<input type="paasword" name="paasword" onChange={ this.saveFormData('password') } />
            <button>登录</button>
          </form>
        )
      }
    }
    ReactDOM.render(<Demo />, document.getElementById('test'))

但是会带来一个问题:onChange={this.事件名}是将当前这个事件作为onChange的回调,而onChange={this.事件名(参数)}是将this.事件名(参数)的返回值作为onChange的回调,所以事件里面就要return一个函数,交给onChange作为回调

saveFormData = (dataType) => {
  return (event) => {
    console.log(dataType,event.target.value)
    // 将输入标签的值存到state中
    this.setState = {
      [dataType]: event.target.value
    }
  }
}

saveFormData方法就是函数柯里化的写法:通过saveFormData函数调用继续返回的函数,接受的参数最后统一处理

为什么上述函数中dataType的外层要包一个[ ]?

let a = 'name'
let obj = {}
/* 如果想实现这种数据格式:
obj: {
  name: 'tom'
}
*/
// 就要这样写
obj[a] = 'tom'

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>高阶函数_函数柯里化</title>
</head>
<body>
  <div id="test"></div>

  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  <script src="https://cdn.staticfile.org/prop-types/15.6.1/prop-types.js"></script>

  <script type="text/babel">
    class Demo extends React.Component {
      state = {
        username: '',
        password: ''
      }
      handleSubmit = (event) => {
        event.preventDefault()
      }
      saveUsername = (event) => {
        this.setState({ username: event.target.value })
      }
      savePaasword = (event) => {
        this.setState({ paasword: event.target.value })
      }

      /*
        高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数
          1. 若A函数,接受的参数是一个函数,那么A就可以称之为高阶函数
          2. 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数
          常见的高阶函数有:
            Promise  new Promise((resolve, reject) => {})
            setTimeout  setTimeout(() => {}, 2000)
            数组身上的一些方法  例如:arr.map()
        
        函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式
       */

      //  saveFormData方法就是函数柯里化的写法:通过saveFormData函数调用继续返回的函数,接受的参数最后统一处理
      saveFormData = (dataType) => {
        return (event) => {
          console.log(dataType,event.target.value)
          // 将输入标签的值存到state中
          this.setState = {
            /*
              此处的dataType外面为何要包一层[]?
              let a = 'name'
              let obj = {}
              // 如果想实现这种数据格式:
              obj: {
                name: 'tom'
              }
              // 就要这样写
              obj[a] = 'tom'
            */
            [dataType]: event.target.value
          }
        }
      }
      render() {
        return (
          <form onSubmit={ this.handleSubmit }>
            {/* 可输入的表单标签,如果想实现vue那样的双向绑定:数据修改页面实时更新,就需要使用onChange事件和setState去改变数据的状态
            但是如果可输入的表单标签很多,每个标签都要写个onChange事件,就很麻烦,代码也很冗余 */}
            {/* 用户名:<input type="text" name="username" onChange={ this.saveUsername } />
            密码:<input type="paasword" name="paasword" onChange={ this.savePaasword } /> */}
            {/* 解决方案:给onChange绑定同一个事件,在这个事件中给整个表单的输入标签做状态变更,传一个参数,用来区别当前是哪个输入标签
            但是会带来一个问题:onChange={this.事件名}是将当前这个事件作为onChange的回调,而onChange={this.事件名(参数)}是将this.事件名(参数)的返回值作为onChange的回调
            所以事件里面就要return一个函数,交给onChange作为回调
          */}
            用户名:<input type="text" name="username" onChange={ this.saveFormData('username') } />
            密码:<input type="paasword" name="paasword" onChange={ this.saveFormData('password') } />
            <button>登录</button>
          </form>
        )
      }
    }
    ReactDOM.render(<Demo />, document.getElementById('test'))
  </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值