美文网首页现代前端指南!
浅谈react 高阶组件

浅谈react 高阶组件

作者: 云高风轻 | 来源:发表于2021-12-01 17:09 被阅读0次

    1. 前言

    1.高阶组件是 react组件总结中最难的一种,平常基本用不到,就算能用到也给规避了,所以也导致很多人不会
    2.这几天结合之前的一些粗浅经验,搞了个简单的梳理,最终梳理出几个相对简单易懂的课件,不足之处,欢迎交流


    2. 是什么 what

    高阶组件(Higher Order Component,简称:HOC ):

    1.是 React 中用于重用组件逻辑的高级技巧.
    2.HOC 自身不是 React API的一部分,它是一种基于 React 的组合特性而形成的设计模式
    3.高阶组件参数为组件,返回值为新组件的函数


    简单理解

    一个高阶组件只是一个包装了另外一个 React 组件的 组件。
    这种形式通常实现为一个函数,本质上是一个类工厂(class factory


    3.优点

    1.实现了对原有组件的增强和优化,
    2.可以对原有组件中的state, props和逻辑执行增删改操作, 一般用于代码重用和组件增强优化


    4. 应用场景

    1. 需要代码重用时, react如果有多个组件都用到了同一段逻辑, 这时,就可以把共同的逻辑部分提取出来,利用高阶组件的形式将这段逻辑整合到每一个组件中, 从而减少代码的逻辑重复
    1. 需要组件增强优化时, 比如我们在项目中使用的组件有些不是自己写的, 而是从网上撸下来的,但是第三方写的组件可能比较复杂, 有时不能完全满足需求, 但第三方组件不易修改, 此时也可以用高阶组件,在不修改原始组件的前提下, 对组件添加满足实际开发需求的功能
      3.其实主要就是针对优点 的应用
      4.也可以用来替换 mixins 混入

    4. 组件和 高阶组件的区别

    1.组件是将 props 转换为 UI
    2.高阶组件是将组件转换为另一个组件


    5. 实现方式

    5.1 属性代理

    (Props Proxy): 通过创建新组件来包裹原始组件, 把原始组件作为新组件的子组件渲染
    功能: 可实现对原始组件的 props数据更新 和 组件模板更新


    5.2 反向继承

    (Inheritance Inversion): 通过创建新组件继承自原始组件, 把原始组件作为父组件
    功能: 可实现对原始组件的state状态数据更新 和 组件模板更新


    好了已经一大堆理论了,上代码 再接着理论

    6. 铺垫 引出工作/代码

    6.1 代码

        localStorage.setItem("userInfo", JSON.stringify({ name: "yzs", description: "生活如此多娇" }))
            class UserView extends React.Component {
                constructor(props) {
                    super(props)
                    this.state = { userInfo: {} }
    
                }
                componentDidMount() {
                    let userInfo = JSON.parse(localStorage.getItem("userInfo"))
                    this.setState({ userInfo })
                }
                render() {
                    let { userInfo } = this.state
                    return (
                        <div>
                            <h1>{userInfo.name}</h1>
                            <p>{userInfo.description}</p>
                        </div>
                    )
                }
            }
    

    6.2 分析

    1.上述 获取 userInfo的逻辑要在好多地方使用,
    2.那么在使用的地方都需要重写 constructor componentDidMount ,显然这是冗余操作
    3.这个时候需要代码 重用,所以可以选择高阶组件,对应上述的优点之一


    7. 属性代理 用法

    高阶函数的基本结构是 函数,参数是组件,返回新的组件
    所以基本写法都是差不多的

    7.1 基本结构

            function withUserData(WrappedComponent) {
                return class extends React.Component {
                    constructor(props) {
                        super(props)
                        this.state = { userInfo: {} }
    
                    }
                    componentDidMount() {
                        let userInfo = JSON.parse(localStorage.getItem("userInfo"))
                        this.setState({ userInfo })
                    }
                    render() {
                        // ...this.props 传递给当前组件的属性继续向下传递
                        return <WrappedComponent userInfo={this.state.userInfo} {...this.props} />
                    }
                }
            }
    

    7.2 分析

    1.函数名字可以随便起
    2.参数名一般都是WrappedComponent, ed代表被包裹 ,所以整体代表 被包裹的组件,


    注意

    3.这里只封装了获取 userInfo数据的逻辑,render,布局可以不管
    4.然后以属性的形式传递给包装的组件WrappedComponent
    5.WrappedComponent 中直接通过 props属性获取需要的数据
    6.其他组件也需要这段逻辑时就可以通过withUserData 高阶组件包装组件来使用


    拔高

    1.高阶组件的主要功能是封装并分离组件的通用逻辑,让通用逻辑在组件间更好地被复用。
    2.高阶组件的这种实现方式,本质上是一个装饰者设计模式。


    8. 使用高阶组件

    8.1 需要使用的组件

      class UserView2 extends React.Component {
                render() {
                    // 注意这里变为 props属性接收传值
                    let { userInfo } = this.props
                    return (
                        <div>
                            <h1>{userInfo.name}</h1>
                            <p>{userInfo.description}</p>
                        </div>
                    )
                }
                // 省略其他逻辑,重点是当前知识点
            }
    

    这个组件也需要用到获取 userInfo数据的逻辑


    8.2 和高阶组件联合使用

            const UserHOC = withUserData(UserView2)
    

    函数调用,参数是组件


    8.3 显示

     let App = () => {
                return (
                    <div>
                        <h1>App</h1>
                        <UserView />
                        <UserHOC />
                    </div>
                )
            }
            ReactDOM.render(<App />, document.querySelector("#app"))
    

    直接作为组件来使用


    9. 高阶组件与父组件区别

    这里很多道友有疑问了,这不和父组件一样嘛干啥这么麻烦呢

    1.首先从逻辑的执行流程上来看,高阶组件确实和父组件比较相像,
    2.但是高阶组件强调的是逻辑的抽象。高阶组件是一个函数,函数关注的是逻辑;
    3.父组件是一个组件,组件主要关注的是UI/DOM。如果逻辑是与DOM直接相关的,那么这部分逻辑适合放到父组件中实现;
    4.如果逻辑是与DOM不直接相关的,那么这部分逻辑适合使用高阶组件抽象,如数据校验、请求发送等。


    10.后续

    看来一篇文章还真不行,接着写


    参考资料

    react-组件总结
    react 高阶组件-中文官网


    初心

    我所有的文章都只是基于入门,初步的了解;是自己的知识体系梳理,如有错误,道友们一起沟通交流;
    如果能帮助到有缘人,非常的荣幸,一切为了部落的崛起;
    共勉

    相关文章

      网友评论

        本文标题:浅谈react 高阶组件

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