从零开始学React-coderwhy React课程笔记(九)

受控和非受控组件-高阶函数-高级组件和应用

受控组件与非受控组件

在 React 中,表单元素通常会保存在一些内部的 state,例如表单的值绑定到一个 state。此时,该表单的值的获取和更新都由 React 代码进行控制 (而不是原生的 HTML 表单元素自身控制)。被 React 以这种方式控制取值的表单输入元素就叫做 "受控组件";

受控有点类似于 Vue 的双向绑定,但在 React 里你要自己控制表单的值。即绑定了一个 value 属性时,要弄一个 onChange 监听。

非受控组件:表单数据将交由 DOM 节点来处理;开发中受控组件用得比较多。

受控组件例子

模拟一个表单提交:

javascript 复制代码
handleSubmitClick(event) {
  // 1.阻止表单提交的默认行为
  event.preventDefault()
  // 2.获取到表单数据
  console.log(this.state.username)
  // 3.发送网络请求
}
​
handleUsernameChange(event){
  this.setState({ username: event.target.value })
}
​
handlePasswordChange(event){
  this.setState({ password: event.target.value })
}
​
render(){
  <div>
    <form onSubmit={ e => handleSubmitClick(e)}>
      <lable htmlFor="username">
        <input 
          type="text"
          id="username"
          name="username"
          value={username}
          onChange={e => handleUsernameChange(e)}
        />
      </lable>
      <lable htmlFor="password">
        <input 
          type="text"
          id="password"
          name="password"
          value={password}
          onChange={e => handlePasswordChange(e)}
        />
      </lable>
      <button type="submit">提交</button>
    </form>
  </div>
}

但上面有一个问题是:每添加一个表单项,就要再加一个handle的方法,有没有什么可以复用的方式,写一个方法就行。

可以使用ES6的一个语法:计算属性名

csharp 复制代码
handleInputChange(event){
  this.setState([event.target.name]: event.target.value)
}

课上还讲了常见的表单元素 checkbox,select 的受控组件例子...重点就是如何维护表单的 state,state 的形式是怎样的(数组、对象等)。

coderwhy老师的学习小建议:

  • 先去看官方文档最权威,官方文档没有的话去 StackOverflow 上搜
  • 代码的一些高级语法不用死记硬背完全背住,因为记不住。自己多写,不会的时候再看之前写过的代码就能熟练用了。分清哪些重要哪些不重要
  • 做好学习的规划

高阶组件

高阶函数

满足以下两个条件之一:

  • 接受一个或多个函数作为输入;
  • 输出一个函数;

filtermapreduce 都是高阶函数。

高阶组件定义

高阶组件(HOC)是以参数为组件,返回值为新组件的函数

高阶组件的作用

对传入的组件进行一层拦截操作,再根据该组件增强得到新组件。

高阶组件的应用

1. Props 的增强

利用高阶组件,可以很方便地添加新的 props

javascript 复制代码
function enhanceProps(originalComponent, newProps) {
  return props => <WrapperCpn {...props} {newProps} />
}

但以上加 props 的做法在开发中很少使用。一个真实的应用场景是利用高阶组件来共享 Context 。可以将 Contextvalue 注入过程写成一个高阶组件,就不用每次都写 ThemeContext.Consumer

javascript 复制代码
import ThemeContext from "../context/ThemeContext"
​
function withTheme(originComponent){
  return props => {
    return (
      <ThemeContext.Consumer>
        {
          value => {
            return <OriginComponent {...value} {...props}/>
          }
        }
      </ThemeContext.Consumer>
    )
  }
}
export default withTheme

这样只需要导出时使用高阶组件再包裹一层,就能取到Contextvalue

scala 复制代码
export class Product extends PureComponent {
  render() {
    const {color,size} = this.props
    
    return (
      <div>Product: {color}</div>
    )
  }
}
​
export default withTheme(Product)

2. 渲染判断鉴权

登录鉴权:如果登录成功,展示购物车页面,否则展示登录提示

javascript 复制代码
function loginAuth(OriginComponent) {
  return props => {
    const token = localStorage.getItem("token")
    
    if(token) {
      return <OriginComponent {...props}/>
    } else {
      return <h2>请先登录,再跳转到对应页面中</h2>
    }
  }
}
export default loginAuth

3. 生命周期劫持

4. 之前接触过的高阶组件

  • memo
  • forwardRef

高阶组件的缺点

  • HOC需要在原组件上进行包裹或者嵌套,如果大量使用HOC,将会产生非常多的嵌套
  • HOC可以劫持props,在不遵守约定的情况下也可能造成冲突
相关推荐
黑叶白树9 分钟前
简单的签到程序 python笔记
笔记·python
qq_3901617713 分钟前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test43 分钟前
js下载excel示例demo
前端·javascript·excel
幸运超级加倍~1 小时前
软件设计师-上午题-15 计算机网络(5分)
笔记·计算机网络
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶1 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo1 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
知孤云出岫1 小时前
web 渗透学习指南——初学者防入狱篇
前端·网络安全·渗透·web