从零开始学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,在不遵守约定的情况下也可能造成冲突
相关推荐
GesLuck13 分钟前
C#控件开发3—文本显示、文本设值
前端·c#
轻口味19 分钟前
【每日学点鸿蒙知识】屏幕高度、证书签名、深色模式对上架影响、Taskpool上下文、List触底加载更多
前端·华为·harmonyos
冴羽1 小时前
Solid.js 最新官方文档翻译(12)—— 派生信号与 Memos
前端·javascript·react.js
萧大侠jdeps2 小时前
Vue 3 与 Tauri 集成开发跨端APP
前端·javascript·vue.js·tauri
红色的山茶花3 小时前
YOLOv9-0.1部分代码阅读笔记-train.py
笔记·深度学习·yolo
JYeontu3 小时前
实现一个动态脱敏指令,输入时候显示真实数据,展示的时候进行脱敏
前端·javascript·vue.js
发呆的薇薇°3 小时前
React里使用uuid插件--生成随机的id
react.js·uuid·javascirpt
发呆的薇薇°3 小时前
react里使用Day.js显示时间
前端·javascript·react.js
嘤嘤嘤3 小时前
基于大模型技术构建的 GitHub Assistant
前端·github
KeepCatch3 小时前
CSS 动画与过渡效果
前端