高阶组件

简单来说,高阶组件可以看做一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。

我在之前的博客《闭包和类》中提到一个观点,面向对象的好处就在于,易于理解,方便维护和复用。

其实高阶组件,也是为了更好地复用之前的组件。它可以理解为,基础组件通过包裹处理,生成一个适应某些场景的组件。

它可能存在于以下几种场景:

定制props

一个简单例子:

function withMoreThings(WrappedComponent) {
return class extends React.Component {
render() {
const moreThings = {
more: 'things',
};
return <WrappedComponent {...this.props} ...moreThings/>
}
}
}

这是HOC(High Order Component)最常用的一种方式,用来传递一些定制化的参数给内部组件。

提取公共方法、属性

在to B的项目中,表单是一个大头,所有流程都绕不开表单。也就会说到受控组件和非受控组件。

受控组件

由于HTML表单元素会保留一些内部状态,比如input框,它会有自己内部的状态来保存用户的输入值。

<input type="text" name="name" />

此时,为了能够处理将React的state和表单元素的内部状态统一起来,React提供了一种称为“受控组件”的技术。

class NameInput extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''}; this.handleChange = this.handleChange.bind(this);
} handleChange(event) {
console.log(this);
this.setState({value: event.target.value});
} render() {
return (
<input type="text" value={this.state.value} onChange={this.handleChange} />
);
}
}

通过内部的state和绑定change事件,就可以将input内部的处理机制转移到React的默认处理机制上,收到React的控制。

但是,还是有一些元素,不能使用这种方法,比如

<input type="file">

这个元素是只读的,用户选择完毕后,可以获取到对应的文件。不能通过React内部的state来模拟。

这就引出了——

非受控组件

非受控组件从DOM中获取表单值,而不是通过React的state来处理。由于它不经过React的一些逻辑,所以不能对它的状态做监控。这里有一篇文章Controlled and uncontrolled form inputs in React don't have to be complicated介绍了何时可以使用非受控组件。

下面是一个非受控组件的例子:

import React, { Component } from "react";
export default class NameInput extends Component {
constructor(props) {
super(props);
} handleChange(event) {
console.log(this);
this.setState({ value: event.target.value });
} render() {
return (
<input
type="text"
defaultValue="test"
ref={input => (this.input = input)}
/>
);
}
}
<input type="checkbox"> 和 <input type="radio"> 支持 defaultChecked,<input type="text"><select> 和 <textarea> 支持 defaultValue,可以帮助设置表单默认值。

非受控组件通过ref来获取DOM元素,然后根据当前DOM去更新UI。

有关Ref的使用,参考这个文档Refs & DOM

我个人建议,如果对于一些数据交互较少,展示和处理基本在组件内部完成,不会涉及到很多组件间数据交换的情景,可以使用非受控组件,更快,更直观。其他情况仍然建议使用受控组件,方便数据流的传导。

接着说回高阶组件。在使用表单时,很多情境下的输入,我们都希望统一由state,或者redux来保存,而不是被dom节点存储。

上面讲到了受控组件的使用,关键点有三:

1.对应的onChange方法

2.对应的存储点,state或者redux

3.绑定到对应组件

参考上面的描述,来实现一个高阶组件的生成函数。

这里是一个例子:https://codesandbox.io/s/7p85l213q

这样就可以很方便的生成受控组件。

在一些场景下,我们也可以用其他组件包装WrappedComponent。比如,添加一些小图标,用父组件可能不够灵活,用HOC则可以很轻松地生成一个可配置的组件,灵活许多。

React Higher Order Components in depth还提到一种生成HOC的方法,类继承,改写更彻底。详细内容可以参考这篇文章。也可以查看知乎的这篇翻译深入理解 React 高阶组件

以上,感谢阅读。

react系列(二)高阶组件-HOC的更多相关文章

  1. React中的高阶组件

    高阶组件(HOC, High-Order Component)是React中用于重组组件逻辑的高级技术,是一种编程模式而不是React的api. 直观来讲,高阶组件是以某一组件作为参数返回一个新组件的 ...

  2. 高阶函数 HOF & 高阶组件 HOC

    高阶函数 HOF & 高阶组件 HOC 高阶类 js HOC 高阶函数 HOF 函数作为参数 函数作为返回值 "use strict"; /** * * @author x ...

  3. React中的高阶组件,无状态组件,PureComponent

    1. 高阶组件 React中的高阶组件是一个函数,不是一个组件. 函数的入参有一个React组件和一些参数,返回值是一个包装后的React组件.相当于将输入的React组件进行了一些增强.React的 ...

  4. React: 高阶组件(HOC)

    一.简介 如我们所知,JavaScript有高阶函数这么一个概念,高阶函数本身是一个函数,它会接收或者返回一个函数,进而对该函数进行操作.其实,在React中同样地有高阶组件这么一个东西,称为HOC, ...

  5. 高阶组件 HOC

    一. A higher-order component (HOC) is an advanced technique in React for reusing component logic. a h ...

  6. 高阶函数HOF和高阶组件HOC(Higher Order Func/Comp)

    一.什么是高阶函数(组件),作用是什么? 子类使用父类的方法可以通过继承的方式实现,那无关联组件通信(redux).父类使用子类方法(反向继承)呢 为了解决类(函数)功能交叉/功能复用等问题,通过传入 ...

  7. React进阶之高阶组件

    前言 本文代码浅显易懂,思想深入实用.此属于react进阶用法,如果你还不了解react,建议从文档开始看起. 我们都知道高阶函数是什么, 高阶组件其实是差不多的用法,只不过传入的参数变成了react ...

  8. 函数式编程与React高阶组件

    相信不少看过一些框架或者是类库的人都有印象,一个函数叫什么creator或者是什么什么createToFuntion,总是接收一个函数,来返回另一个函数.这是一个高阶函数,它可以接收函数可以当参数,也 ...

  9. 聊聊React高阶组件(Higher-Order Components)

    使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...

随机推荐

  1. Iphone各个型号机型的详细参数,尺寸和dpr以及像素

    1.iPhone尺寸规格 2.单位inch(英吋) 1 inch = 2.54cm = 25.4mm 3.iPhone手机宽高 上表中的宽高(width/height)为手机的物理尺寸,包括显示屏和边 ...

  2. H5前端的关于像素解释

    场景: 人物:前端实习生「阿树」与 切图工程师「玉凤」 事件:设计师出设计稿,前端实现页面 玉凤:树,设计稿发给你啦,差那么点像素,就叼死你┏(  ̄へ ̄)=☞ 阿树:~(>_<)~毛问题噶 ...

  3. COGS 有标号的二分图计数系列

    其实这三道题都是不错的……(虽然感觉第三题略套路了……) 分别写一下做法好了…… COGS2392 有标号的二分图计数 I 这个就很简单了,Noip难度. 显然可以直接认为黑点和白点分别位于二分图两侧 ...

  4. WebClient用法小结(转载)

    如果只想从特定的URI请求文件,则使用WebClient,它是最简单的.NET类,它只用一两条命令执行基本操作,.NET FRAMEWORK目前支持以http:.https:.ftp:.和 file: ...

  5. _itoa atoi、atof、itoa、itow _itoa_s 类型转换使用说明

    原文:http://www.cnblogs.com/lidabo/archive/2012/07/10/2584706.html _itoa 功能:把一整数转换为字符串 用法:char * _itoa ...

  6. Oracle基础之count(1)和count(*)的区别

    在数据库中Count(*)或者Count(1)或者Count([列])或许是最常用的聚合函数.很多人其实对这三者之间是区分不清的.本文会阐述这三者的作用,关系以及背后的原理. 我在网上看到一些所谓的优 ...

  7. undo表空间不足,ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS2'

    故障现象:UNDO表空间越来越大,长此下去最终数据因为磁盘空间不足而崩溃: 问题分析:本问题在ORACLE系统管理中属于比较正常的一现象,产生问题的原因主要以下两点: 1. 有较大的事务量让Oracl ...

  8. SQL Server ->> SQL Server 2016重要功能改进之 -- INSERT SELECT时并发插入数据

    SQL Server 2016对INSERT INTO XXXX SELECT语句进行了优化,在某些情况下可以触发数据的并行插入,但是要求兼容模式是130(SQL Server 2016)以及在插入的 ...

  9. 新款Macbook 安装任意来源软件教程 mac软件下载资源推荐

    防止无良爬虫,开头附上原文链接:http://www.cnblogs.com/xueyudlut/p/7810981.html ------分割线--------------------------- ...

  10. lua之m进制转换为n进制-任意进制转换算法

    够无聊的写这个,为防止需要的人也无聊一遍,写个吧 算法有n种,但是,咱们一种就够用了 --数组倒序排列 local function orderByDesc( input ) local output ...