为了提高代码的复用在react中我们可以使用高阶组件

1.添加高阶组件

高阶组件主要代码模板HOC.js

export default (WrappedComponent) => {
return class extends Component {
constructor(props) {
super(props)
this.state = { //定义可复用的状态 }
this.getCode = this.getCode.bind(this)
} componentWillMount() { }
    //定义可复用的方法
getCode(mobile) {
...
}
postVcode(mobile) {
...
}
render() {
return (
<div>
<WrappedComponent getCode={this.getCode} state={this.state} {...this.props}/>
</div>
)
}
}
}

注:其中<WrappedComponent />的自定义属性getCode与state传递了对外可以用的方法与属性

2.在其他组件中使用高阶组件

register.js

import HOC from 'common/js/HOC'
class Register extends Component{
  ...
  ...
}
export default HOC(Register)

或者也可以使用装饰器语法书写

import HOC from 'common/js/HOC'
@HOC
class Register extends Component{
...
}
export default Register

3.完整示例代码

例如 发送短信验证码功能在注册于忘记密码2个组件中都用到了,我们可以把它抽离到HOC中

HOC.js

import React, {Component} from 'react'
import axios from 'axios'
import qs from 'qs'
import { noToken } from './config' import { loadToken } from 'common/js/cache'
import { url } from 'common/js/config'
let token = loadToken()
console.log('token', token);
export default (WrappedComponent) => {
return class extends Component {
constructor(props) {
super(props)
this.state = {
codeBtnText: '发送验证码'
}
this.getCode = this.getCode.bind(this)
this.postVcode = this.postVcode.bind(this)
}
componentWillMount() { }
getCode(mobile) {
if (mobile === '') {
this.setState({
tipsText: '请输入手机号码'
})
this.refs.confirm.show()
return
}
if (!/1[3|4|5|7|8]\d{9}/.test(mobile)) {
this.setState({
tipsText: '请输入正确手机号码'
})
this.refs.confirm.show()
return
}
this.codeBtnDisable = true
// console.log(this.codeBtnDisable)
this.postVcode(mobile)
let total = 59
this.setState({codeBtnText: `${total}秒`})
// this.codeBtnText = `${total}秒`
this.timer = setInterval(() => {
// console.log(total)
--total
// this.codeBtnText = `${total}秒`
this.setState({codeBtnText: `${total}秒`})
if (total <= 0) {
clearInterval(this.timer)
// this.codeBtnText = '发送验证码'
this.setState({codeBtnText: `发送验证码`})
this.codeBtnDisable = false
}
}, 1000)
}
postVcode(mobile) {
var _params = {
Phone: mobile
}
var that = this
axios({ method: 'post',
url: url + 'ComService/PostVcode',
data: _params
})
.then(function (res) {
if (res.data.issuccess) {
that.setState({
tipsText: res.data.message
})
that.refs.confirm.show()
//that.saveUserApplyStepList(res.data.result)
} else {
that.setState({
tipsText: res.data.message
})
that.refs.confirm.show()
that.codeBtnDisable = false
clearInterval(that.timer)
// that.codeBtnText = `发送验证码`
this.setState({codeBtnText: `发送验证码`})
return false
}
})
.catch(function (error) {
console.log(error)
})
}
render() {
return (
<div>
<WrappedComponent getCode={this.getCode} state={this.state} {...this.props}/>
</div>
)
}
}
}

register.js

import React, {Component} from 'react'
import axios from 'common/js/http'
import { url } from 'common/js/config'
import Confirm from 'base/confirm/confirm'
import { withRouter } from 'react-router-dom'
import { setToken } from 'common/js/cache'
import getCodeHOC from 'common/js/HOC'
@getCodeHOC
class Register extends Component{ constructor() {
super()
this.state = {
mobile: '',
password: '',
tipsText: '',
isOpen: false,
inputType: 'password',
codeBtnText: '发送验证码'
}
this.confirm = React.createRef()
this.buttonBtn = React.createRef()
this.handleMobileChange = this.handleMobileChange.bind(this)
this.handlePassWordChange = this.handlePassWordChange.bind(this)
this.handleLogin = this.handleLogin.bind(this)
this.switchEye = this.switchEye.bind(this)
this.goToLogin = this.goToLogin.bind(this)
// this.getCode = this.getCode.bind(this)
this.btnDisable = false
this.codeBtnDisable = false
// this.codeBtnText = '发送验证码'
this.timer = null
}
componentDidMount() {
let _mobile = localStorage.getItem('mobile')
this.setState({
mobile: _mobile
})
}
handleMobileChange (e) {
this.setState({
mobile: e.target.value
})
}
handleLogin (e) {
let that = this
let params = {
Identifier:this.state.mobile,
Credential:this.state.password
}
if (params.Identifier === '') {
this.setState({
tipsText:'请输入手机号码'
})
this.refs.confirm.show()
return
}
if (!/1[3|4|5|7|8]\d{9}/.test(params.Identifier)) {
this.setState({
tipsText:'请输入正确手机号码'
})
this.refs.confirm.show()
return
}
if (params.Credential === '') {
this.setState({
tipsText:'请输入密码'
})
this.refs.confirm.show()
return false
}
axios({ method: 'post',
url: url + 'Login/UserLogin',
data: params
}).then((res) => {
// console.log(res);
if (res.data.issuccess) {
console.log(that.props);
window.location.href = '/home'
setToken(res.data.result.Token)
localStorage.setItem('mobile', that.state.mobile)
} else {
that.setState({
tipsText: res.data.message
})
that.refs.confirm.show()
}
})
}
handlePassWordChange(e) {
this.setState({
password: e.target.value
})
}
switchEye () {
this.setState(prevState => ({
isOpen: !prevState.isOpen
}), ()=> {
this.state.isOpen ? this.setState({inputType: 'text'}) : this.setState({inputType: 'password'})
})
}
shouldComponentUpdate(nextProps, nextState) {
// console.log('nextProps', nextProps);
console.log('nextState', nextState);
if (nextState.mobile && (/1[3|4|5|7|8]\d{9}/.test(nextState.mobile)) && nextState.password ) {
this.btnDisable = true
} else {
this.btnDisable = false
}
if (nextState.codeBtnText === '发送验证码') {
this.codeBtnDisable = false
}
return true
}
goToLogin () {
console.log(this.props);
this.props.history.push('/login')
}
render() {
return (
<div>
<div className="title">用户注册</div>
<div className="inputBox padType">
<div className="input size-0 align-1">
<label >手机号</label>
<input type="tel" placeholder="请输入手机号" maxLength="11" value={this.state.mobile} onChange={this.handleMobileChange} />
</div>
</div>
<div className="inputBox padType">
<div className="input size-0 align-1">
<label >验证码</label>
<input placeholder="请输入密码" maxLength="6" type="number"/> <div className={"send-smg-code " + (this.codeBtnDisable ? 'disable' : '')} onClick={()=>this.props.getCode(this.state.mobile)}>{this.props.state.codeBtnText}</div>
</div>
</div>
<div className="inputBox padType">
<div className="input size-0 align-1">
<label >密&nbsp;&nbsp;&nbsp;&nbsp;码</label>
<input placeholder="请输入密码" maxLength="16" type={this.state.inputType} onChange={this.handlePassWordChange}/>
<div className="eye" onClick={this.switchEye}>
</div>
</div>
</div>
<div className="agree-register">
<div className="agree-check"></div> <div className="agree-text">
同意《
<a href="#/useAgreementRegister">
注册协议
</a>

</div>
</div>
<div className="buttonBox disable">
<div className={"button " + (this.btnDisable ? '' : 'disable')}>
注册
</div>
</div>
<div className="child-mt20"> <div className="buttonBox reverse">
<div className="button reverse" onClick={this.goToLogin}>
已有账号,去登录
</div>
</div>
</div>
<Confirm text={this.state.tipsText} confirmType='2' ref="confirm"></Confirm>
</div>
)
} }
export default withRouter(Register)

forgetpassword.js

import React, {Component} from 'react'
import axios from 'common/js/http'
import { url } from 'common/js/config'
import Confirm from 'base/confirm/confirm'
import { withRouter } from 'react-router-dom'
import { setToken } from 'common/js/cache'
import HOC from 'common/js/HOC'
// @HOC
class Forgetpassword extends Component{
constructor() {
super()
this.state = {
mobile: '',
password: '',
tipsText: '',
isOpen: false,
inputType: 'password',
codeBtnText: '发送验证码'
}
this.confirm = React.createRef()
this.buttonBtn = React.createRef()
this.handleMobileChange = this.handleMobileChange.bind(this)
this.handlePassWordChange = this.handlePassWordChange.bind(this)
this.handleLogin = this.handleLogin.bind(this)
this.switchEye = this.switchEye.bind(this)
// this.getCode = this.getCode.bind(this)
this.btnDisable = false
this.codeBtnDisable = false
// this.codeBtnText = '发送验证码'
this.timer = null
}
componentDidMount() {
let _mobile = localStorage.getItem('mobile')
this.setState({
mobile: _mobile
})
}
handleMobileChange (e) {
this.setState({
mobile: e.target.value
})
} handleLogin (e) {
let that = this
let params = {
Identifier:this.state.mobile,
Credential:this.state.password
}
if (params.Identifier === '') {
this.setState({
tipsText:'请输入手机号码'
})
this.refs.confirm.show()
return
}
if (!/1[3|4|5|7|8]\d{9}/.test(params.Identifier)) {
this.setState({
tipsText:'请输入正确手机号码'
})
this.refs.confirm.show()
return
}
if (params.Credential === '') {
this.setState({
tipsText:'请输入密码'
})
this.refs.confirm.show()
return false
}
axios({ method: 'post',
url: url + 'Login/UserLogin',
data: params
}).then((res) => {
// console.log(res);
if (res.data.issuccess) {
console.log(that.props);
// window.location.href = '/home'
let _href = window.location.href
let _hrefArr = _href.split('#')
window.location.href = _hrefArr[0] + '#/home'; //太low了。。。。
setToken(res.data.result.Token)
localStorage.setItem('mobile', that.state.mobile)
} else {
that.setState({
tipsText: res.data.message
})
that.refs.confirm.show()
}
})
}
handlePassWordChange(e) {
this.setState({
password: e.target.value
})
}
switchEye () {
this.setState(prevState => ({
isOpen: !prevState.isOpen
}), ()=> {
this.state.isOpen ? this.setState({inputType: 'text'}) : this.setState({inputType: 'password'})
})
}
shouldComponentUpdate(nextProps, nextState) {
// console.log('nextProps', nextProps);
console.log('nextState', nextState);
if (nextState.mobile && (/1[3|4|5|7|8]\d{9}/.test(nextState.mobile)) && nextState.password ) {
this.btnDisable = true
} else {
this.btnDisable = false
}
if (nextState.codeBtnText === '发送验证码') {
this.codeBtnDisable = false
}
return true
}
render() {
return (
<div>
<div className="title">忘记密码</div>
<div className="inputBox padType">
<div className="input size-0 align-1">
<label >手机号</label>
<input type="tel" placeholder="请输入手机号" maxLength="11" value={this.state.mobile} onChange={this.handleMobileChange}/>
</div>
</div>
<div className="inputBox padType">
<div className="input size-0 align-1">
<label >验证码</label>
<input placeholder="请输入密码" maxLength="6" type="number"/>
<div className={'send-smg-code ' + (this.codeBtnDisable ? 'disable' : '')} onClick={(e) => this.props.getCode(this.state.mobile)}>{this.props.state.codeBtnText}</div>
</div>
</div>
<div className="inputBox padType">
<div className="input size-0 align-1">
<label >新密码</label>
<input placeholder="请输入密码" maxLength="16" type={this.state.inputType} onChange={this.handlePassWordChange}/>
<div className={ 'eye ' + (this.state.isOpen ? 'open' : '')} onClick={this.switchEye}></div>
</div>
</div>
<div className="buttonBox ">
<div className={'button ' + (this.btnDisable ? '': "disable")} ref={this.buttonBtn} onClick={this.handleLogin}>
确定
</div>
</div> <Confirm text={this.state.tipsText} confirmType='2' ref="confirm"></Confirm>
</div>
)
}
}
export default withRouter(HOC(Forgetpassword))

4.注意点

一、使用装饰器语法需要安装transform-decorators-legacy插件并配置package

1.npm install babel-plugin-transform-decorators-legacy --save-dev

2.配置package中babel下plugin

 "babel": {
"presets": [
"react-app"
],
"plugins": ["transform-decorators-legacy"]
},

二、高阶组件中的复用方法或状态属性需要在其他组件中使用记得作为属性传递出去,以便其他组件使用

react高阶组件的使用的更多相关文章

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

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

  2. 当初要是看了这篇,React高阶组件早会了

    当初要是看了这篇,React高阶组件早会了. 概况: 什么是高阶组件? 高阶部件是一种用于复用组件逻辑的高级技术,它并不是 React API的一部分,而是从React 演化而来的一种模式. 具体地说 ...

  3. react高阶组件的理解

    [高阶组件和函数式编程] function hello() { console.log('hello jason'); } function WrapperHello(fn) { return fun ...

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

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

  5. React高阶组件学习笔记

    高阶函数的基本概念: 函数可以作为参数被传递,函数可以作为函数值输出. 高阶组件基本概念: 高阶组件就说接受一个组件作为参数,并返回一个新组件的函数. 为什么需要高阶组件 多个组件都需要某个相同的功能 ...

  6. 利用 React 高阶组件实现一个面包屑导航

    什么是 React 高阶组件 React 高阶组件就是以高阶函数的方式包裹需要修饰的 React 组件,并返回处理完成后的 React 组件.React 高阶组件在 React 生态中使用的非常频繁, ...

  7. react高阶组件的一些运用

    今天学习了react高阶组件,刚接触react学习起来还是比较困难,和大家分享一下今天学习的知识吧,另外缺少的地方欢迎补充哈哈 高阶组件(Higher Order Components,简称:HOC) ...

  8. React——高阶组件

    1.在React中higher-order component (HOC)是一种重用组件逻辑的高级技术.HOC不是React API中的一部分.HOC是一个函数,该函数接收一个组件并且返回一个新组件. ...

  9. react 高阶组件的 理解和应用

    高阶组件是什么东西 简单的理解是:一个包装了另一个基础组件的组件.(相对高阶组件来说,我习惯把被包装的组件称为基础组件) 注意:这里说的是包装,可以理解成包裹和组装: 具体的是高阶组件的两种形式吧: ...

随机推荐

  1. ModuleNotFoundError: No module named 'video_back.urls'

    新建Django项目时将settings,urls移除来时报错. 这是我所想要的项目结构  >>>  扁平结构. 将下面这个应用的名字删掉就可以了.

  2. OpenCV中Mat总结

    一.数字图像存储概述 数字图像存储时,我们存储的是图像每个像素点的数值,对应的是一个数字矩阵. 二.Mat的存储 1.OpenCV1基于C接口定义的图像存储格式IplImage*,直接暴露内存,如果忘 ...

  3. centos7端口永久开放方法

    /sbin/iptables -I INPUT -p tcp --dport -j ACCEPT /sbin/iptables -I INPUT -p tcp --dport -j ACCEPT /s ...

  4. 20175226 2018-2019-2 《Java程序设计》第二周学习总结

    20175226 2018-2019-2 <Java程序设计>第二周学习总结 教材学习内容总结 基本数据类型与数组 标识符与关键字 标识符不能是关键字.true.false.null.且第 ...

  5. JavaScript入门学习笔记(异常处理)

    try:语句测试代码块的错误,当try中的代码块出错时执行catch中的代码块. catch:语句处理错误: throw:语句创建或抛出自定义异常. 三者一起使用可以控制程序流并生成自定义异常信息. ...

  6. Zabbix告警发送邮件时附带性能图

    脚本处理逻辑分析: 通过zabbix传递给脚本的message参数,筛选出报警信息的itemid; 通过itemid获取到图片并保存; 将报警信息和图片组装成html; 发送邮件. 后续脚本里面的处理 ...

  7. James Munkres Topology: Theorem 16.3

    Theorem 16.3 If \(A\) is a subspace of \(X\) and \(B\) is a subspace of \(Y\), then the product topo ...

  8. Expression Trees 参数简化查询

    ASP.NET MVC 引入了 ModelBinder 技术,让我们可以在 Action 中以强类型参数的形式接收 Request 中的数据,极大的方便了我们的编程,提高了生产力.在查询 Action ...

  9. Android 调用 .NET WebService

    1.下载并导入jar工具类包 打开下载界面http://simpligility.github.io/ksoap2-android/getting-started.html ,拉倒最下 2.Copy ...

  10. XV Open Cup named after E.V. Pankratiev. GP of America

    A. Area of Effect 首先最优解中必有一个点在圆的边界上. 若半径就是$R$,则枚举一个点,然后把剩下的事件极角扫描即可,时间复杂度$O(m(n+m)\log(n+m))$. 否则圆必然 ...