为了提高代码的复用在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. 【转】Java中的static关键字解析

    一.static关键字的用途 在<Java编程思想>P86页有这样一段话: “static方法就是没有this的方法.在static方法内部不能调用非静态方法,反过来是可以的.而且可以在没 ...

  2. 新增项目到GIT仓库中

    在本地新建项目的目录中打开Git Bash命令行工具 运行以下命令,设置全局信息(包括用户名,邮箱地址) git config --global user.name "你的姓名" ...

  3. Java面试题复习笔记(前端)

    1.Html,CSS,Jsp在网页开发中的定位? Html——定义网页结构(超文本标记语言) CSS——层叠样式表,用来美化界面 Jsp——主要用来验证表单,做动态交互(Ajax) 2.介绍Ajax? ...

  4. Java的家庭记账本程序(K)

    日期:2019.3.10 博客期:043 星期日 呕吼~这里是编程菜鸟小Master,今天加油的把第二个模板套用了,更改了许多的设定,我想这一个程序的网页版也就到这里结束了,下面是一部分的展示图,想要 ...

  5. Mac OS X系统下,svn: Can't remove file Operation not permitted.解决方案

    当你的svn出现类似以下错误时,提示Operation not permitted之类的问题,说明项目下 .svn文件夹内的文件权限有问题. 一般是由于windows和mac操作系统同时操作同个svn ...

  6. sass进阶—mixin的使用(浏览器兼容性调整)

    @mixin content($color:red,$fontSize:14px){ color:$color; font-size: $fontSize;} /*调用含参数的mixin,使用更加灵活 ...

  7. ssh项目问题01,为创建数据库抛出的异常

    框架什么都搭建好了,但是一直抛出如图问题,网上资料很多让你设置时间之类的,也设置了还是继续抛异常,最后带我的师傅说没有创建数据库,我都要郁闷死了,网上那么多,很多写的都不能解决问题,还乱写,浪费别人时 ...

  8. 为什么用Flow

    Flow 是 facebook 出品的 JavaScript 静态类型检查工具.Vue.js 的源码利用了 Flow 做了静态类型检查,所以了解 Flow 有助于我们阅读源码. flow的工作方式? ...

  9. codeforces 502 g The Tree

    题解: 一道优秀的题目 有几种做法: 1.维护后缀和 刚开始我想的是维护前缀和 然后用$sum[x]-sum[y]>=dep[x]-dep[y]$来做 但是这样子树赋值为0这个操作就很难进行了 ...

  10. 动态dp

    题解: 首先这类题目本身是一个dp/树形dp 然后带上了修改(ddp) 为了权衡查询和修改的时间,我们采用树剖来维护 假设我们能够对每个点维护除了重儿子之外的信息 那么我们的修改只需要修改log个节点 ...