高阶函数的基本概念
在了解高阶组件之前我们先了解高阶函数是什么:
- 函数可以被作为参数传递;
setTimeout(()=>{
console.log("react高阶函数")
},1000)
- 函数可以作为返回值输出;
function foo ( x ){
return function(){
return x
}
}
高阶函数的应用
- 高阶函数在时间函数上的应用
setTimeout(function(){
console.log("hello word")
},1000)
setInterval(() => {
console.log("hello react")
}, 1000);
- 高阶函数在jquery ajax中的应用
$.get("/api/getUserInfo",function(res){
console.log(res)
})
- es5中数组的迭代方法:
some() 、every() 、filter()、map()、forEach()
高阶组件的基本概念(High Order Component, HOC)
高阶组件就是接受一个组件作为参数并返回一个新组件的函数,高阶组件是一个函数,并不是组件
- 高阶组件示例;
function A(WrappedComponent){
return class A extends Component{
render(){
return(
<div>
<div>提示</div>
<WrappedComponent/>
</div>
)
}
}
}
- 为什么需要高阶组件
多个组件需要相同的功能,使用高阶组件减少重复实现,react-redux中的connect函数就是高阶组件
export default connect(mapStateToProps,mapDispatchToProps)(Header)
如何编写一个高阶组件
- 变写普通组件
- 将普通组件使用函数包裹
// 编写普通组件
class D extends Component{
render(){
return(
<div>
</div>
)
}
}
// 定义一个函数包裹刚刚编写的组件
import React, { Component } from 'react'
function d(){
return class D extends Component{
render(){
return(
<div>
</div>
)
}
}
}
//高阶函数编写完成将其导出
export default d
- 使用高阶组件
//直接调用
higherOrderComponent(WrappendComponent)
//使用装饰器语法,注意:使用装饰器需要安装相关的插件
@higherOrderComponent
高阶组件的应用
代理方式的高阶组件
返回的新组件直接继承自React.Component类,,新组件扮演的角色是传入参数组件的一个代理,在新的组件的render函数中,将被包裹组件渲染出来,除了高阶组件自己要做的工作,其余功能全部都转手给了被包裹的组件
export default () => WrappedConponent => class A extends Component {
render(){
const {...otherProps} = this.props
return <WrappedConponent {...otherProps} />
}
}
继承方式的高阶组件
采用继承关联作为参数的组件和返回的组件,加入传入的组件参数是WrappedComponent,那么返回的组件
就是直接继承自WrappedComponent
export default () => WrappedConponent => class A extends WrappedConponent {
render(){
const {age,...otherProps} = this.props
this.props = otherProps
return super.render()
}
}
两者的区别
代理方式:直接继承React.Component
继承方式:直接继承 WrappedComponent
代理的方式是优于继承方式,优先考虑代理的方式的高阶组件,然后在考虑继承方式的高阶组件
代理方式高阶组件的应用
1.操纵prop: 高阶组件能够改变被包裹组件的props
//props的增加
export default (title) => WrappedComponent => class A extends Component{
render(){
return(
<div>
<div>{ title }</div>
<WrappedComponent gender={"男"} {...this.props} />
</div>
)
}
}
//props的删减
export default (title) => WrappedComponent => class A extends Component{
render(){
const {age, ...otherProps} = this.props 删除age这个属性值
return(
<div>
<div>{ title }</div>
<WrappedComponent gender={"男"} {...otherProps} />
</div>
)
}
}
2.访问ref :获取被包装组件的实例
export default (title) => WrappedComponent => class A extends Component{
refc(instance){
instance.getName&&console.log(instance.getName()) //如果存在这个方法就输出这个方法返回值
}
render(){
const {age, ...otherProps} = this.props 删除age这个属性值
return(
<div>
<div>{ title }</div>
<WrappedComponent gender={"男"} {...otherProps} ref={this.refc.bind(this)} />
</div>
)
}
}
//使用
import A from './A'
@A("我是组件e")
class E extends Component {
getName(){
return '我是组件e'
}
render(){
return (
<div>
<span>hello word </span>
</div>
)
}
}
export default E
- 抽取状态
export default (title) => WrappedComponent => class A extends Component{
constructor(props){
this.state = {
value :""
}
}
onInputChange = (e) => {
this.setState = {
value :e.target.value
}
}
render(){
const newProps = {
value: this.state.value,
onInput:this.onInputChange
}
return(
<div>
<div>{ title }</div>
<WrappedComponent {...newProps} />
</div>
)
}
}
// 使用
import A from './A'
@A("我是组件e")
class F extends Component {
constructor(props){}
render(){
return (
<div>
<input type="text" {this.props} />
</div>
)
}
}
export default F
继承方式高阶组件的应用
1.操纵prop: 高阶组件能够改变被包裹组件的props
const modifyHoc (WrappedComponent) => class A extends WrappedComponent{
render(){
const element = super.render()
const newStyle = {
color:element.type === 'div' ? 'red' : 'green'
}
const newProps = {...this.props,style:newStyle}
return React.cloneElement(element,newProps,element.props.children)
}
}
//使用
import React, {Component} from 'react'
import modify from './D'
@modify
class G extends from Component{
render(){
return (
<div>hello div</div>
)
}
}
1.操纵生命周期函数:
const modifyHoc (WrappedComponent) => class A extends WrappedComponent{
componentWillMount(){
console.log("我是修改后的生命周期函数")
}
render(){
const element = super.render()
const newStyle = {
color:element.type === 'div' ? 'red' : 'green'
}
const newProps = {...this.props,style:newStyle}
return React.cloneElement(element,newProps,element.props.children)
}
}
//使用
import React, {Component} from 'react'
import modify from './D'
@modify
class G extends from Component{
componentWillMount(){
console.log("我是原始生命周期函数")
}
render(){
return (
<div>hello div</div>
)
}
}