前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在 React 中使用装饰器-即@修饰符

如何在 React 中使用装饰器-即@修饰符

作者头像
itclanCoder
发布2020-12-14 17:03:28
3K0
发布2020-12-14 17:03:28
举报
文章被收录于专栏:itclanCoderitclanCoder

虽互不曾谋面,但希望能和您成为笔尖下的朋友

以读书,技术,生活为主,偶尔撒点鸡汤

不作,不敷衍,意在真诚吐露,用心分享

点击左上方,可关注本刊

标星公众号(ID:itclanCoder)

如果不知道如何操作

点击这里,标星不迷路

前言

装饰器 decorator 是一种函数,是 Es6 的一个语法糖,是一种与类(class)相关的语法,用来注释或修改类和方法

@+函数名形式展现,可以放在类和类方法的定义前面

那它在 React 中是如何使用的呢,这里以create-react-app脚手架搭建的项目为例

01

为什么要使用装饰器模式?

在设计模式中讲到优先使用对象而不是类继承,动态的给对象添加一些额外的属性或方法,相比与使用继承,装饰器模式更加灵活

在 React 中,高阶组件是一个非常厉害的东西,它最大的特点就是能够:重用组件逻辑.达到精简代码能力

前提条件

在使用这种装饰器方式时,需要对create-react-app做一些配置,它默认是不支持装饰器模式的,需要对项目做一些配置

在项目根目录中终端下使用npm run eject,这条命令主要是将我们的配置项做一个反向输出,暴露出隐藏的 webpack 配置项,这样可以项目进行修改了的,注意它是不可逆的

方式 1-经过 eject 后在 package.json 中的 plugins 中配置

使用装饰器,需要使用babel来进行转换,用到的插件是@babel/plugin-proposal-decorators

当用ejectwebpack一些配置弹射出来以后,会看到根目录下的package.json文件下新增了很多文件

babel对象处进行插件的配置,将@babel/plugin-proposal-decorators添加到plugins

代码语言:javascript
复制
{
  "babel": {
    "presets": [
      "react-app"
    ],

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

  }
}

注意

create-react-app 脚手架中已经安装了 @babel/plugin-proposal-decorators 插件,如果是自己配置的脚手架,则先要安装插件:`npm install @babel/plugin-proposal-decorators --save-dev

当然有一个比较便捷的写法就是使用安装babel-plugin-transform-decorators-legacy

代码语言:javascript
复制
{
  "babel": {
    "presets": [
      "react-app"
    ],

  "plugins":[
    "transform-decorators-legacy"
   ]

  }
}

注意

如果使用的是 vscode, 可以在项目根目录下添加 jsconfig.json 文件来消除代码警告

代码语言:javascript
复制
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

或者在 vscode 中的设置中tsconfig启动Experimental Decorators就可以解决此警告

方式 2-安装 babel 插件在 babelrc 中配置

在使用这种装饰器方式时,需要对create-react-app做一些配置,它默认是不支持装饰器模式的,你需要对项目做一些配置

create-react-app根目录中终端下使用npm run eject,这条命令主要是将我们的配置项做一个反向输出,暴露出隐藏的 webpack 配置项,这样可以项目进行修改了的,注意它是不可逆的

使用装饰器模式时:需要安装两个依赖:

代码语言:javascript
复制
cnpm install -D babel-preset-stage-2
cnpm install -D babel-preset-react-native-stage-0

然后你需要在根目录下创建一个.babelrc文件,对.babelrc文件做一些配置

代码语言:javascript
复制
{
  "presets": ["react-native-stage-0/decorator-support"]
}

经过这么配置后,就可以使用装饰器了的

02

未使用装饰器之前

如下是componentA.js一个高阶组件

代码语言:javascript
复制
import React, { Component } from 'react';

function A(WrappedComponent) {
  // 函数接收一个组件为参数,并返回一个类组件,继承自Component
  return class componentA extends Component {
    render() {
      return (
        <div>
          <WrappedComponent />
        </div>
      );
    }
  };
}

export default A;

如下componentB.js一个组件

代码语言:javascript
复制
import React, { Component } from 'react';
import A from './componentA'; // 引入高阶组件

class componentB extends Component {
  render() {
    return <div>我是组件B</div>;
  }
}

export default A(componentB); // 直接调用A,将组件componentB作为参数传入

如果嵌套层次很多,会发现这种代码不优雅,很难理解,如果用装饰器,就解决了多层嵌套的问题

03

使用装饰器后

componentB.js组件中

代码语言:javascript
复制
import React, { Component } from 'react';
import A from './componentA'; // 引入高阶组件

@A // 直接@+函数名就可以了的
class componentB extends Component {
  render() {
    return <div>我是组件B</div>;
  }
}

export default componentB; // 这里直接返回componentB组件

你可以给高阶组件添加静态属性,以及实例属性

代码语言:javascript
复制
import React, { component } from 'react';

function Foo(params) {
  params.title = 'itclanCoder';
  params.prototype.decorator =
    'decorator是装饰器,即@+函数名,用来注释或修改类方法';
}

@Foo
class ComponentA extends Component {
  render() {
    return (
      <div>
        <p>{ComponentA.title}</p>
        <p>{ComponentA.decorator}</p>
      </div>
    );
  }
}

在调用装饰器的时候,可以往里面传入实参,则在函数需要return一个函数,return 返回的函数参数是类的本身,下面的 Foo 函数可以接受参数,这就等于可以修改装饰器的行为

代码语言:javascript
复制
import React, { component } from 'react';

function Foo(isAble) {
  return function(target) {
    target.isAble = isAble;
  };
}

@Foo(false)
class ComponentA extends Component {
  render() {
    return <div>{componentA.isAble} // false</div>;
  }
}

04

TypeScript

如果你的项目已经开始使用TypeScript,那我们只需要在tsconfig.json文件中的 experimentalDecorators 设置为 true

就可以使用 ES7 新特性装饰器了

解决 vscode 中不支持 decorator 语法警告问题

在项目根目录创建tsconfig.json,设置如下所示

代码语言:javascript
复制
{
    "compilerOptions": {
        "experimentalDecorators": true,
        "allowJs": true
    }
}

注意事项

⒈ 装饰器对类的行为的改变时代码编译时发生的,而不是在运行时,这意味着,装饰器能在编译阶段运行代码,它本身就是编译时执行的函数

⒉ 装饰器只能用于类和类的方法,不能用于函数,因为它存在函数提升

结语

高阶组件是函数,参数是组件并返回一个组件的函数,允许向一个现有的对象添加新的功能,增加静态属性于实例属性,又不改变结构,属于包装器模式的一种

因为 Es7 中添加了 decorator 属性,使用@函数名表示,在编写 React 组件时,高阶组件是一个非常实用的东西

或许不知不觉中,自己就已经实现了的,很久以前看过设计模式中的装饰器模式,一直云里雾里,不知道这个东西有什么用

直到它在 React 中高阶组件还可以简写,这么用..

如果您有关装饰器问题,欢迎给我留言,一起学习探讨

相关参考文档

  • 装饰器-decorator(https://es6.ruanyifeng.com/#docs/decorator)
  • 原文出处:https://coder.itclan.cn/fontend/framework/advance-react-use-decorator/
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 itclanCoder 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 01
    • 前提条件
      • 方式 1-经过 eject 后在 package.json 中的 plugins 中配置
      • 方式 2-安装 babel 插件在 babelrc 中配置
      • 在componentB.js组件中
  • 02
  • 03
  • 04
    • 解决 vscode 中不支持 decorator 语法警告问题
      • 注意事项
        • 结语
          • 相关参考文档
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档