为了提高代码的复用在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. HTML5 web存储之LocalStorage和sessionStorage

    什么是localstorage 前几天在老项目中发现有对cookie的操作觉得很奇怪,咨询下来是要缓存一些信息,以避免在URL上面传递参数,但没有考虑过cookie会带来什么问题: ① cookie大 ...

  2. PGCD2 - Primes in GCD Table (Hard)

    这题肝了三四天,其他啥也没做... 传送门 然后...双倍经验 简单版 不知道为什么会脑抽去帮 LZ_101 大佬验题... 题目和被 A 穿的 PGCD 一样,数据范围变成大概 2e11 ... 于 ...

  3. npm——安装教程、安装vue脚手架

    npm:是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题.比如常用的有: 1)允许用户从NPM服务器下载别人编写的第三方包到本地使用. 2)允许用户从NPM服务器下载并安 ...

  4. 【原创】大数据基础之Zookeeper(3)选举算法

    提到zookeeper选举算法,就不得不提Paxos算法,因为zookeeper选举算法是Paxos算法的一个变种: Paxos要解决的问题是:在一个分布式网络环境中有众多的参与者,但是每个参与者都不 ...

  5. 【原创】大数据基础之ElasticSearch(5)重要配置及调优

    Index Settings 重要索引配置 Index level settings can be set per-index. Settings may be: 1 static 静态索引配置 Th ...

  6. 使用putty连接Ubuntu虚拟机,使用ssh方式访问

    1 前言 Ubuntu14.04版本是可以直接连接的,没想到新装的Ubuntu18.04竟然没有默认安装ssh. 则安装一下open-ssh-server就可以的. 2 步骤 2.1 更新一下源 命令 ...

  7. php 常用的自定义函数

    1. 发送 SMS 在开发 Web 或者移动应用的时候,经常会遇到需要发送 SMS 给用户,或者因为登录原因,或者是为了发送信息.下面的 PHP 代码就实现了发送 SMS 的功能. 为了使用任何的语言 ...

  8. VUE中总的逻辑关系和移动端mint-ui的应用接触

    1.mint-ui官网:https://mint-ui.github.io/#!/zh-cn 可以点击开始使用,里边有详细的讲解.安装mint-ui: 官网是: 但是应用没有装成功,不知为何,可能是我 ...

  9. jQuery 第六章 jQuery在Ajax应用

    1.本章目标 ajax 2.ajax 异步刷新技术,我们的网页不需要全部刷新,按需实现局部刷新,上线后台的交互 用户体验好 地图,前台验证,表单提交,修改,查询等等 原生的js和ajax packag ...

  10. python的位置参数、默认参数、关键字参数、可变参数区别

    一.位置参数 调用函数时根据函数定义的参数位置来传递参数. #!/usr/bin/env python # coding=utf-8 def print_hello(name, sex): sex_d ...