React 使用高阶组件封装Context的两种方式

Reac中使用Context共享数据时,可以使用高阶组件做一个封装,方便页面使用

方式一:使用高阶组件

1.在App.js中添加状态共享Provider

import Home from './page/Home'
import {Provider, Context} from './AppContext'

const store = {
  user: {
    isLogin: true,
    userName: "Kevin"
  }
}

function App() {
  return (
    <div className="App">
      <Provider value={store}>
        <Home/>
      </Provider>
    </div>
  );
}

export default App;

2.创建AppContext.js,在文件中添加状态消费Consumer

import React from 'react';

export const Context = React.createContext()
export const Provider = Context.Provider
export const Consumer = Context.Consumer

export const ConsumerHandle = Cmp => props => {
    return <Consumer>
        {
            ctx => <Cmp {...props} {...ctx} />
        }
    </Consumer>
}

3.在页面中使用高阶组件

import React, { Component } from 'react'
import { ConsumerHandle } from '../../AppContext'

function Home(props) {
    return <div>账号:{props?.user?.userName}</div>
}
export default ConsumerHandle(Home);

方式二:使用装饰器

1.create-react-app项目,使用 npm run eject 弹射出config配置文件夹

2.安装装饰器支持babel依赖 npm install --save-dev @babel/plugin-proposal-decorators

3.创建和修改jsconfig.json,解决vscode中不支持decorator语法警告问题

{
    "compilerOptions": {
        "experimentalDecorators": true,
        "allowJs": true
    }
}

4.修改package.json

"babel": {
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }]
  ],
  "presets": [
    "react-app"
  ]
}

5.修改AppContext.js,导出装饰器

import React, { Component } from 'react';

export const Context = React.createContext()
export const Provider = Context.Provider
export const Consumer = Context.Consumer

export const ConsumerHandle = parms => Cmp => {
    return class PageNormal extends Component {
        render() {
            return <Consumer>
                {
                    ctx => <Cmp {...this.props} {...ctx} />
                }
            </Consumer>
        }
    }
}

6.修改page/Home.js,使用装饰器

import React, { Component } from 'react'
import { ConsumerHandle } from '../../AppContext'

@ConsumerHandle()
class Home extends Component {
    render() {
        return <div>账号:{this.props?.user?.userName}</div>
    }
}

export default Home;

注意事项

  • 装饰器只能用于类和类的方法,不能用于函数,因为它存在函数提升
  • 装饰器只能在编译阶段运行代码,而非在运行时执行
  • ⾼阶组件本身是对装饰器模式的应⽤,所以可以使用装饰器语法来书写代码
posted @ 2021-07-04 20:31  KevinTseng  阅读(293)  评论(0编辑  收藏  举报