Декораторы ES 6 и компоненты высшего порядка React

React.js

Я не очень понимаю, был ли Decorator представлен в ES 6 или ES 7. Есть два типа утверждений. Такого рода проблемы слишком ленивы, чтобы запутаться... Я нашел эту вещь очень полезной, когда я ее использовал, но это может быть не очень полезно в обычное время, но хорошо работает с React. Давайте поговорим об этом далее.

1. Строительство окружающей среды

Я создал среду разработки React в сочетании с плагинами Babel.babel-plugin-transform-decorators-legacyПри совместном использовании этот плагин позволяет вам писать декораторы.

Адрес гитхаба:https://github.com/zhongdeming428/HOC

Его можно клонировать с помощью следующей команды:

$ git clone https://github.com/zhongdeming428/HOC.git

После того, как вы клонируете его, вы можете попробовать его!

Во-вторых, основное использование декоратора

Сам декоратор - это функция, и она очень проста в использовании. Это не что иное, как функция украшения класса или класса. использовать@Вызовите его и бросьте перед классом или методом класса, который нужно изменить. Но есть тонкие различия, когда дело доходит до оформления классов и функций класса.

class A {
    @sayB
    sayA() {
        console.log('a');
    }
}
function sayB(target, name, descriptor) {
    // ...
}

При декорировании функции класса с помощью декоратора она может принимать три параметра. Первый — это декорируемый объект, второй — имя декорируемого свойства, а третий — дескриптор свойства. Вы можете попробовать это в проекте, который я построил.

При декорировании класса декоратором он может принимать только один параметр — target. Это отличается от случая выше:

@APlus
class A {

}
function APlus(target, name, descriptor) {
    // ... 打印一下可以发现 name、descriptor 是 undefined。
}

Кроме того, декоратор также может принимать параметры и возвращать новую функцию, которая соответствует спецификации декоратора, чтобы можно было настроить поведение декоратора. Например:

@attach2Prop({ name: 'A' })
class A {

}

@attach2Prop({ name: 'B' })
class B {

}

function attach2Prop(obj) {
    return function(target) {
        target.prototype.$data = obj;
    }
}

console.log((new A()).$data.name);
console.log((new B()).$data.name);

результат будет выведенAа такжеB.

Это позволяет использовать один и тот же декоратор для реализации различных вариантов поведения.

Итак, каковы преимущества объединения React?

3. Используйте с React

(1) Упростите использование React-Redux

В прошлом при использовании react-redux после определения компонентов пользовательского интерфейса мы также определяли компоненты-контейнеры:

class UIComponent extends React.Component {

}

const ContainerComponent = connect(mapState2Props, mapDispatch2Props)(UIComponent);

export default ContainerComponent;

После декоратора:

@connect(mapState2Props, mapDispatch2Props)
class UIComponent extends React.Component {

}

export default UIComponent;

Это дает тот же эффект с упрощенным кодом, но также избавляет от проблем с именованием компонентов контейнера... и код становится намного чище.

(2) Настройка компонентов высокого порядка

Компонент-контейнер в предыдущем разделе на самом деле является компонентом более высокого порядка, но иногда нам приходится самим определять некоторые компоненты более высокого порядка, чтобы добиться повторного использования кода на более высоком уровне.

Например, мы сделали библиотеку компонентов, и некоторые компоненты в ней имеют функциональную особенность, то есть их можно перетаскивать; другой пример — сделанный нами мобильный компонент, в котором нужно реализовать удаление левым свайпом функция. Нужно ли нам писать логику перетаскивания или удаления смахиванием влево для каждого компонента с этой функцией?

Очевидно, что нет, мы можем реализовать компонент чистой логики, а не компонент пользовательского интерфейса, его функция состоит в том, чтобы сделать ваш компонент пользовательского интерфейса определенным. Например, левым свайпом удалить или перетащить упомянутое выше.

Этот компонент чистой логики может быть декоратором, компонентом более высокого порядка.

В среде разработки, которую я создал, я реализовал такой простой высокоуровневый компонент, благодаря которому ваш компонент пользовательского интерфейса выглядит как рука при перемещении мыши.

Код декоратора выглядит следующим образом:

// src/decorators/CursorPointer.js
import React from 'react';

export default Component => class extends React.Component {
  render() {
    return <div style={{cursor: 'pointer', display: 'inline-block'}}>
      <Component/>
    </div>
  }
}

Этот декоратор (компонент более высокого порядка) принимает компонент React в качестве параметра и возвращает новый компонент React. Реализация очень проста, просто оберните слой div и добавьте стиль, это так просто. Все будущие компоненты, украшенные им, будут иметь эту особенность.

Используйте этот декоратор:

import React from 'react';
import Clickable from '../decorators/CursorPointer';

@Clickable
class ClickablePanel extends React.Component {
  render() {
    return <div className="panel">

    </div>
  }
}

export default ClickablePanel;

Сочетание декораторов с компонентами более высокого порядка может значительно оптимизировать ваш код React!