美文网首页
React 高阶组件

React 高阶组件

作者: 读书的鱼 | 来源:发表于2019-03-20 09:17 被阅读0次

第一章 引导

image.png

学习之前要有一定的:es6基础、js面向对象编程、react的一些基础知识

第二章 高阶组件介绍

2-1 高阶函数

1、高阶函数的两个基本特征

//1.函数可以做为参数被传递
setTimeout(function(){
  console.log(1)
},1000)

//2.函数可以作为返回值输出
function student(name){
  return function(){
    return name
  }
}

2、应用场景:
1).高阶函数在时间函数的应用

setTimeout()
setInterval()

2).高阶函数在ajax中的应用

$.get('/api/api.json',function(){
    console.log('获取成功')
})

3).高阶函数在数组中的应用

some()
every()
filter()
map()
forEach()
2-2 高阶组件介绍

1、高阶组件基本概念(High Order Component,HOC)
高阶组件就是:接受一个组件作为参数并返回一个新的组件的函数
高阶组件:是一个函数,并不是组件
代码演示地址:https://gitee.com/sunnyfan/react-hight-order-component.git

git clone https://gitee.com/sunnyfan/react-hight-order-component.git
cd react-hight-order-component
npm install
npm start

代码截取

//1.组件A是公共组件,且被定义为一个高阶组件(高阶函数)
import React, {Component} from 'react';
function A(WrappedComponent) {
    return class A extends Component {
        render() {
            return (
                <div className="container">
                    <div className="header">
                        <span>提示</span>
                        <span>X</span>
                    </div>
                    <div className="content">
                        <WrappedComponent></WrappedComponent>
                    </div>
                </div>
            );
        }
    }
}
export default A;

//B组件
import React, {Component} from 'react';
import A from './A';
class B extends Component {
    render() {
        return (
            <div>
                B
            </div>
        );
    }
}
export default A(B);

//C组件
import React, {Component} from 'react';
import A from './A';
class C extends Component {
    render() {
        return (
            <div>
                c
            </div>
        );
    }
}
export default A(C);

应为A组件是公共组件,在B和C组件中都被使用到了,所以可以把A抽离成为公共组件
2、使用场景
多个组件都需要某个相同的功能,使用高阶组件减少重复实现
3、高阶组件实例
react-redux中的connect
export default connect(mapStateToProps,mapDispatchToProps)(Header);

第三章 高阶组价实现

3-1编写高阶组件

1.实现一个普通组件
2.将普通组件使用函数包裹

//第一步:实现一个普通组件
import React, {Component} from 'react';
class A extends Component {
    render() {
        return (
            <div>
                A
            </div>
        );
    }
}
export default A;

//将普通组件使用函数包裹
import React, {Component} from 'react';
function A(WrappedComponent) {
    return class A extends Component {
        render() {
            return (
                <div className="container">
                        <WrappedComponent />
                </div>
            );
        }
    }
}
export default A;
3-1使用高阶组件

1.higherOrderComponent(WrappedComponent);
2.@higherOrderComponent 通过装饰器
要想使用装饰器的用法:那么我们需要对项目进行一些配置
1).开启webpack配置项

在创建的create-react-app项目中 运行 npm run eject

2).安装两个依赖包

npm install babel-preset-stage-2 -D
npm install babel-preset-react-native-stage-0 -D

或者(简写如下):
npm install babel-preset-stage-2  babel-preset-react-native-stage-0  -D

3).项目根目录创建.babelrc配置文件

//.babelrc
{
"presets":["react-native-stage-0/decorator-support"]
}

ps:如果上面出现报错
Cannot find module 'react-native-stage-0/decorator-suppor

npm install metro-react-native-babel-preset -D
将.babelrc改为
{
  "presets": ["module:metro-react-native-babel-preset"],
   "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }]   
  ]
}

配置好后,那么怎么在项目中使用@装饰器来替代写法呢

import React, {Component} from 'react';
import A from './A';

@A  //第二种使用方法:通过装饰器
class B extends Component {
    render() {
        return (
            <div>
                B
            </div>
        );
    }
}

//export default A(B);  第一种使用方法:高阶组件的普通使用
export default B //如果上面使用了@A 那么这个地方直接这样写即可

第四章高阶组件的应用

4-1 高阶组件的代理方式

1、代理方式的高阶组件
返回的新组件类直接继承自React.Component
新组件扮演的角色传入参数组件的一个代理,在新组件的render函数中,将被包裹组件渲染出来,除了高阶组件自己要做的工作,其他功能全局转手给了被包裹的组件

  • 操纵prop
  • 抽离状态
  • 访问ref
  • 包装组件
    1.1.操纵props
    高阶组件是如何向子组件传递参数或者值的呢?
    高阶组件是如何去除组件当中的属性或者值的呢?
import React, {Component} from 'react';
function A(WrappedComponent) {
    return class A extends Component {
        render() {
            const {age, ...otherProps} = this.props
            return (
                <div className="container">
                    <div className="header">
                        <span>提示</span>
                        <span>X</span>
                    </div>
                    <div className="content">
                        <WrappedComponent 
                          name={'张三'} 
                          sex={'男'} 
                          {...otherProps} 
                        />
                    </div>
                </div>
            );
        }
    }
}
export default A;

通过属性值 给子组件传值:age={'18'}
通过结构的方式去除,其他的参数或者属性:

//这样就把age的属性从所有属性值剔除出去了
const {age, ...otherProps} = this.props;
 <WrappedComponent 
    name={'张三'} 
    sex={'男'} 
    {...otherProps} 
/>

1.2.访问ref

//A组件
import React, {Component} from 'react';
function A(WrappedComponent) {
    return class A extends Component {
        componentDidMount() {
            const value = this.refs
            console.log(value.getName())
        }      
        render() {
            const {age, ...otherProps} = this.props
            return (
                <div className="container">
                    <div className="header">
                        <span>提示</span>
                        <span>X</span>
                    </div>
                    <div className="content">
                        <WrappedComponent
                            name={'张三'}
                            sex={'男'}
                            {...otherProps}
                            ref={(value) => this.refs = value}>
                        </WrappedComponent>
                    </div>
                </div>
            );
        }
    }
}
export default A;

//B组件
import React, {Component} from 'react';
import A from './A';

@A
class B extends Component {
    getName() {
        return '我是B组件'
    }

    render() {
        const {name, age, sex} = this.props;
        return (
            <div>
                B
            </div>
        );
    }
}

export default B;

1.3 抽取状态

//A组件
import React, {Component} from 'react';

function A(WrappedComponent) {
    return class A extends Component {
        constructor(props) {
            super(props);
            this.state = {
                inputValue: '张三'
            }
        }

        handleChangeValue = (e) => {
            const value = e.target.value;
            this.setState({
                inputValue: value
            })
        }

        render() {
            const {age, ...otherProps} = this.props;
            const {inputValue} = this.state;
            const newProps = {
                value: inputValue,
                onChange: this.handleChangeValue,
                placeholder: '张三'
            }
            return (
                <div className="container">
                    <div className="header">
                        <span>提示</span>
                        <span>X</span>
                    </div>
                    <div className="content">
                        <WrappedComponent
                            name={'张三'}
                            sex={'男'}
                            {...otherProps}
                            {...newProps}
                        />
                    </div>
                </div>
            )
                ;
        }
    }
}
export default A;

//B组件
import React, {Component} from 'react';
import A from './A';

@A
class B extends Component {
    render() {
        const {age, sex, ...newProps} = this.props;
        return (
            <div>
                <p>
                    <label>请输入我的名字:</label>
                    <input
                        type="text"
                        value={newProps.value}
                        onChange={newProps.onChange}
                        placeholder={newProps.placeholder}
                    />
                </p>
                <p>
                    我的名字:{newProps.value}
                </p>
            </div>
        );
    }
}
export default B;

4-2 继承方式的高阶组件
采用继承关联作为参数的组件和返回的组件,假如传入的组件参数是WrappedComponent,那么返回的组件就直接继承自WrappedComponent
2.1代理方式的高阶组件和继承方式的高阶组件的区别

区别
  • 操作props
  • 操作生命周期函数
//组件D 继承方式的高阶组件
import React from 'react';
const modifyPropsHOC = (WrappedComponent) => class NewComponent extends WrappedComponent {
    componentWillMount() {
        alert('我是在继承生命周期函数')
    }
    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)
    }
};
export default modifyPropsHOC

//E组件 继承D里面一些
import React, {Component} from 'react';
import D from './D';

@D
class E extends Component {
    componentWillMount() {
        alert('我是原始生命周期函数')
    }
    render() {
        return (
            <div>
                我是div
            </div>
        );
    }
}
export default E;

ps:我们应该“代理方式”优先于“继承方式”的
所以我们在开发过程中,尽量是用代理方式的高阶组件
4-3高阶组件显示名
通过高阶组件中有一个displayName的属性来显示的

import React from 'react';

const modifyPropsHOC = (WrappedComponent) => class NewComponent extends WrappedComponent {
    static displayName = `NewComponent(${getDisplayName(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)
    }
};

function getDisplayName(WrappedComponent) {
    return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}

export default modifyPropsHOC
效果

第五章 高阶组件的实际应用-底部导航切换

效果图

代码地址

git clone https://gitee.com/sunnyfan/react-hight-order-component.git
git checkout feature/shili

相关文章

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

    什么是 React 高阶组件 React 高阶组件就是以高阶函数的方式包裹需要修饰的 React 组件,并返回处理...

  • React 进阶之高阶组件

    高阶组件 HOC 高阶组件(HOC)是react中的高级技术,用来重用组件逻辑。但高阶组件本身并不是React A...

  • 高阶组件

    React 高阶组件HOC (Higher-Order Component) 高阶组件是react中重复使用组件逻...

  • React高阶组件

    1、React高阶组件

  • React高阶组件HOC

    高阶组件本质是函数,参数是 组件1 返回组件2,高阶组件是为了复用通用逻辑高阶组件eg:import React,...

  • React高阶组件(HOC)

    高阶组件(Higher-Order Components) 高阶组件(HOC)是 React 中用于重用组件逻辑的...

  • react 笔记

    react 基本概念解析 react 的组件声明周期 react 高阶组件,context, redux 等高级...

  • ReactNative中的高阶组件(HOC)和继承详解

    ReactNative中的高阶组件(HOC)和继承详解 共同点: 高阶组件(HOC)是 React 中用于复用组件...

  • React高阶组件

    React高阶组件 在开始聊高阶组件之前我们先来看下高阶函数和高阶组件在形式上的差异: 一、什么是装饰器模式: 要...

  • React 高阶组件

    当 React 组件被包裹时(wrapped),高阶组件会返回一个增强(enhanced)的 React 组件。高...

网友评论

      本文标题:React 高阶组件

      本文链接:https://www.haomeiwen.com/subject/cwsamqtx.html