Компоненты высшего порядка в React и сценарии их применения

React.js
Компоненты высшего порядка в React и сценарии их применения

Ключевые слова: функции высшего порядка, компоненты высшего порядка, прокси свойств, обратное наследование, шаблон декоратора, управляемые компоненты.

Содержание этой статьи:

  • Что такое компоненты высшего порядка
  • Компоненты высшего порядка в React
    • Реквизит Прокси
    • Инверсия наследования
  • Проблемы с компонентами более высокого порядка
  • Соглашения для компонентов высшего порядка
  • Сценарии применения компонентов высшего порядка
  • Шаблон декоратора? Компоненты высшего порядка? АОП?
  • Суммировать

Что такое компоненты высшего порядка

Прежде чем объяснять, что такое компонент высшего порядка, вы должны сначала понять, что такоеФункции высшего порядка, так как их концепции очень похожи, следующееФункции высшего порядкаОпределение:

если функцияПринимает одну или несколько функций в качестве аргументов или возвращает функциюназови этоФункции высшего порядка.

Вот простая функция высшего порядка:

function withGreeting(greeting = () => {}) {
    return greeting;
}

компоненты более высокого порядкаопределение иФункции высшего порядкаочень похожий:

если функцияПринимает один или несколько компонентов в качестве аргументов и возвращает компонентназови этокомпоненты более высокого порядка.

Вот простой компонент более высокого порядка:

function HigherOrderComponent(WrappedComponent) {
    return <WrappedComponent />;
}

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

Компоненты без состояния также называются функциональными компонентами.

Компоненты высшего порядка в React

В React есть две основные формы компонентов более высокого порядка:Риелтеромиобратное наследование.

Реквизит Прокси

Простейшая реализация прокси свойства:

// 无状态
function HigherOrderComponent(WrappedComponent) {
    return props => <WrappedComponent {...props} />;
}
// or
// 有状态
function HigherOrderComponent(WrappedComponent) {
    return class extends React.Component {
        render() {
            return <WrappedComponent {...this.props} />;
        }
    };
}

Можно обнаружить, что прокси атрибута на самом делеФункция принимаетWrappedComponentКомпонент передается в качестве параметра и возвращает унаследованныйReact.Componentкласс компонента, и в этом классеrender()метод возвращает переданныйWrappedComponentкомпоненты.

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

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

  • действоватьprops
  • отстранитьсяstate
  • пройти черезrefдоступ к экземпляру компонента
  • Оберните входящий компонент другими элементамиWrappedComponent

Реквизит для действий

заWrappedComponentДобавьте новые свойства:

function HigherOrderComponent(WrappedComponent) {
    return class extends React.Component {
        render() {
            const newProps = {
                name: '大板栗',
                age: 18,
            };
            return <WrappedComponent {...this.props} {...newProps} />;
        }
    };
}

состояние извлечения

использоватьpropsи функция обратного вызова поместилаstateВытаскивать:

function withOnChange(WrappedComponent) {
    return class extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                name: '',
            };
        }
        onChange = () => {
            this.setState({
                name: '大板栗',
            });
        }
        render() {
            const newProps = {
                name: {
                    value: this.state.name,
                    onChange: this.onChange,
                },
            };
            return <WrappedComponent {...this.props} {...newProps} />;
        }
    };
}

как пользоваться:

const NameInput = props => (<input name="name" {...props.name} />);
export default withOnChange(NameInput);

Это будетinputПреобразован в управляемый компонент.

Доступ к экземпляру компонента через ref

Иногда возникает необходимость получить доступ к элементу DOM (используя стороннийDOMКомпонент будет использоваться при работе с библиотекой).refАтрибуты. Его можно объявить только для компонентов типа Class, но не для компонентов типа function (без сохранения состояния).

refЗначение может быть строкой (Не рекомендуется) также может быть функцией обратного вызова, если это функция обратного вызова, время ее выполнения:

  • После монтирования компонента (componentDidMount), функция обратного вызова выполняется немедленно, а параметром функции обратного вызова является экземпляр компонента.
  • компонент удален (componentDidUnmount) или оригиналrefПри изменении самого свойства функция обратного вызова также будет выполнена немедленно, и параметры функции обратного вызоваnull.

каккомпоненты более высокого порядкаполучено вWrappedComponentКак насчет экземпляров компонентов? Ответ черезWrappedComponentкомпонентrefсвойство, которое будет использоваться в компонентеcomponentDidMountвыполнить, когдаrefфункцию обратного вызова и передать экземпляр компонента:

function HigherOrderComponent(WrappedComponent) {
    return class extends React.Component {
        executeInstanceMethod = (wrappedComponentInstance) => {
            wrappedComponentInstance.someMethod();
        }
        render() {
            return <WrappedComponent {...this.props} ref={this.executeInstanceMethod} />;
        }
    };
}

Примечание: нельзя использовать для компонентов без состояния (компоненты функционального типа).refсвойство, так как компоненты без состояния не имеют экземпляров.

Оберните входящий компонент другими элементамиWrappedComponent

даватьWrappedComponentЦвет фона слоя пакета компонентов#fafafaизdivэлемент:

function withBackgroundColor(WrappedComponent) {
    return class extends React.Component {
        render() {
            return (
                <div style={{ backgroundColor: '#fafafa' }}>
                    <WrappedComponent {...this.props} {...newProps} />
                </div>
            );
        }
    };
}

Инверсия наследования

Простейшая реализация обратного наследования:

function HigherOrderComponent(WrappedComponent) {
    return class extends WrappedComponent {
        render() {
            return super.render();
        }
    };
}

На самом деле обратное наследованиеФункция принимаетWrappedComponentКомпонент передается в качестве параметра и возвращает компонент, который наследует переданный вWrappedComponentкласс компонента, и в этом классеrender()возврат методаsuper.render()метод.

Вы обнаружите, что реализация его прокси свойств и обратного наследования несколько похожа, обе возвращают подкласс, который наследует родительский класс, но прокси свойств наследуетReact.Component, входящий компонент наследуется в обратном наследованииWrappedComponent.

Для чего можно использовать обратное наследование:

  • действоватьstate
  • Перехват рендеринга

рабочее состояние

Чтение, редактирование и удаление компонентов более высокого порядкаWrappedComponentв экземпляре компонентаstate. даже большеstateпункт, нокрайне не рекомендуетсяпотому что это может привести кstateСложно поддерживать и управлять.

function withLogging(WrappedComponent) {
    return class extends WrappedComponent {
        render() {
            return (
                <div>
                    <h2>Debugger Component Logging...</h2>
                    <p>state:</p>
                    <pre>{JSON.stringify(this.state, null, 4)}</pre>
                    <p>props:</p>
                    <pre>{JSON.stringify(this.props, null, 4)}</pre>
                    {super.render()}
                </div>
            );
        }
    };
}

В этом примере, используя функции более высокого порядка, вы можете прочитатьstateиpropsхарактеристики, даWrappedComponentКомпонент делает вложение дополнительных элементов, помещаяWrappedComponentкомпонентstateиpropsЭто все распечатано,

рендеринг угона

почему это называетсярендеринг угонапотому что компоненты более высокого порядка контролируютWrappedComponentОтрендеренный вывод компонента с помощью перехвата рендеринга мы можем:

  • Условно отображать дерево элементов (element tree)
  • управляетсяrender()Выходное дерево элементов React
  • в любойrender()Действия в выходном элементе Reactprops
  • Оберните входящий компонент другими элементамиWrappedComponent(такой жеРиелтером)
условный рендеринг

пройти черезprops.isLoadingЭто условие определяет, какой компонент визуализировать.

function withLoading(WrappedComponent) {
    return class extends WrappedComponent {
        render() {
            if(this.props.isLoading) {
                return <Loading />;
            } else {
                return super.render();
            }
        }
    };
}
Измените вывод дерева элементов React с помощью render()

Измените дерево элементов:

function HigherOrderComponent(WrappedComponent) {
    return class extends WrappedComponent {
        render() {
            const tree = super.render();
            const newProps = {};
            if (tree && tree.type === 'input') {
                newProps.value = 'something here';
            }
            const props = {
                ...tree.props,
                ...newProps,
            };
            const newTree = React.cloneElement(tree, props, tree.props.children);
            return newTree;
        }
    };
}

Проблемы с компонентами более высокого порядка

  • статический метод отсутствует
  • refsАтрибуты не могут быть прозрачно переданы
  • Обратное наследование не гарантирует, что будет разрешено полное дерево подкомпонентов.

статический метод отсутствует

Поскольку исходный компонент упакован в компонент-контейнер, это означает, что новый компонент не будет иметь никаких статических методов исходного компонента:

// 定义静态方法
WrappedComponent.staticMethod = function() {}
// 使用高阶组件
const EnhancedComponent = HigherOrderComponent(WrappedComponent);
// 增强型组件没有静态方法
typeof EnhancedComponent.staticMethod === 'undefined' // true

Поэтому статический метод необходимо скопировать:

function HigherOrderComponent(WrappedComponent) {
    class Enhance extends React.Component {}
    // 必须得知道要拷贝的方法
    Enhance.staticMethod = WrappedComponent.staticMethod;
    return Enhance;
}

Но одним из недостатков этого является то, что вы должны знать, какой метод копировать, но сообщество React реализовало библиотекуhoist-non-react-staticsчтобы справиться с этим автоматически, он будетАвтоматически копировать все статические методы, отличные от React:

import hoistNonReactStatic from 'hoist-non-react-statics';

function HigherOrderComponent(WrappedComponent) {
    class Enhance extends React.Component {}
    hoistNonReactStatic(Enhance, WrappedComponent);
    return Enhance;
}

Атрибут refs не может быть передан через

В целом компоненты более высокого порядка могут пройти всеpropsдля упакованных компонентовWrappedComponent, но есть одно свойство, которое нельзя передать, этоref. Отличие от других свойств в том, что React обрабатывает их по-особому.

Если вы добавляете к элементу компонента, созданного компонентом более высокого порядкаrefцитата, тогдаrefУказывает на самый внешний экземпляр компонента контейнера, а не на обернутыйWrappedComponentкомпоненты.

Если есть, то его нужно пройтиrefЧто касается потребностей, не волнуйтесь, React предоставляет намReact.forwardRefAPI для решения этой проблемы (добавлено в React 16.3):

function withLogging(WrappedComponent) {
    class Enhance extends WrappedComponent {
        componentWillReceiveProps() {
            console.log('Current props', this.props);
            console.log('Next props', nextProps);
        }
        render() {
            const {forwardedRef, ...rest} = this.props;
            // 把 forwardedRef 赋值给 ref
            return <WrappedComponent {...rest} ref={forwardedRef} />;
        }
    };

    // React.forwardRef 方法会传入 props 和 ref 两个参数给其回调函数
    // 所以这边的 ref 是由 React.forwardRef 提供的
    function forwardRef(props, ref) {
        return <Enhance {...props} forwardRef={ref} />
    }

    return React.forwardRef(forwardRef);
}
const EnhancedComponent = withLogging(SomeComponent);

Обратное наследование не гарантирует, что будет разрешено полное дерево подкомпонентов.

Компоненты React бывают двух видов: тип класса и тип функции (компоненты без сохранения состояния).

Мы знаем, что перехват рендеринга с обратным унаследованием может контролироватьWrappedComponentПроцесс рендеринга, то есть во время этого процесса мы можемelements tree,state,propsилиrender()приводит к различным операциям.

но если рендерингelements treeЕсли компонент содержит компонент функционального типа, вы не можете работать с подкомпонентами компонента в это время.

Соглашения для компонентов высшего порядка

Хотя компоненты высокого порядка приносят нам большое удобство, мы также должны следовать некоторымсоглашение:

  • propsбыть последовательным
  • Вы не можете использовать функциональные (без сохранения состояния) компонентыrefсвойство, потому что у него нет экземпляра
  • Ни в коем случае не изменяйте исходный компонентWrappedComponent
  • Прозрачная передача не имеет значенияpropsатрибут упакованного компонентаWrappedComponent
  • больше не надоrender()Использование компонентов более высокого порядка в методах
  • использоватьcomposeОбъединение компонентов более высокого порядка
  • Отображаемое имя оболочки для упрощения отладки

реквизит последователен

Добавляя функции к подкомпонентам, компоненты более высокого порядка должны стараться максимально сохранить исходные компоненты.propsБез изменений, то есть входящий компонент и возвращенный компонент находятся вpropsБудьте максимально последовательными.

Не изменяйте исходный компонент WrappedComponent

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

function withLogging(WrappedComponent) {
    WrappedComponent.prototype.componentWillReceiveProps = function(nextProps) {
        console.log('Current props', this.props);
        console.log('Next props', nextProps);
    }
    return WrappedComponent;
}
const EnhancedComponent = withLogging(SomeComponent);

Вы обнаружите, что внутри компонента более высокого порядкаWrappedComponentБыли внесены изменения. После изменения исходных компонентов смысл повторного использования компонентов будет потерян, поэтому, пожалуйста, пропуститеЧистая функция (один и тот же вход всегда имеет один и тот же выход)Вернуть новый компонент:

function withLogging(WrappedComponent) {
    return class extends React.Component {
        componentWillReceiveProps() {
            console.log('Current props', this.props);
            console.log('Next props', nextProps);
        }
        render() {
            // 透传参数,不要修改它
            return <WrappedComponent {...this.props} />;
        }
    };
}

После этой оптимизацииwithLoggingЯвляетсячистая функция, не изменяетWrappedComponentКомпоненты, поэтому не нужно беспокоиться о каких-либо побочных эффектах, а затем достичь цели повторного использования компонентов.

Прозрачно передавать нерелевантные реквизиты обернутому компоненту WrappedComponent

function HigherOrderComponent(WrappedComponent) {
    return class extends React.Component {
        render() {
            return <WrappedComponent name="name" {...this.props} />;
        }
    };
}

Не используйте компоненты более высокого порядка в методе render()

class SomeComponent extends React.Component {
    render() {
        // 调用高阶函数的时候每次都会返回一个新的组件
        const EnchancedComponent = enhance(WrappedComponent);
        // 每次 render 的时候,都会使子对象树完全被卸载和重新
        // 重新加载一个组件会引起原有组件的状态和它的所有子组件丢失
        return <EnchancedComponent />;
    }
}

Используйте compose для компоновки компонентов более высокого порядка

// 不要这么使用
const EnhancedComponent = withRouter(connect(commentSelector)(WrappedComponent));
// 可以使用一个 compose 函数组合这些高阶组件
// lodash, redux, ramda 等第三方库都提供了类似 `compose` 功能的函数
const enhance = compose(withRouter, connect(commentSelector));
const EnhancedComponent = enhance(WrappedComponent);

потому что согласносоглашениеРеализованный компонент более высокого порядка на самом деле является чистой функцией, если параметры нескольких функций одинаковы (здесьwithRouterфункция иconnect(commentSelector)Параметры, требуемые возвращаемой функцией:WrappedComponent), так что можно пройтиcomposeспособ совмещения этих функций.

Использование compose для объединения компонентов более высокого порядка может значительно улучшить читаемость кода и его логическую ясность.

Отображаемое имя оболочки для упрощения отладки

Компоненты-контейнеры, созданные компонентами более высокого порядка, ведут себя в React Developer Tools так же, как и любой другой обычный компонент. Для простоты отладки можно выбрать отображаемое имя, чтобы сообщить, что это результат компонента более высокого порядка.

const getDisplayName = WrappedComponent => WrappedComponent.displayName || WrappedComponent.name || 'Component';
function HigherOrderComponent(WrappedComponent) {
    class HigherOrderComponent extends React.Component {/* ... */}
    HigherOrderComponent.displayName = `HigherOrderComponent(${getDisplayName(WrappedComponent)})`;
    return HigherOrderComponent;
}

ФактическиrecomposeВ библиотеке реализованы аналогичные функции, если лень, самому писать не нужно:

import getDisplayName from 'recompose/getDisplayName';
HigherOrderComponent.displayName = `HigherOrderComponent(${getDisplayName(BaseComponent)})`;
// Or, even better:
import wrapDisplayName from 'recompose/wrapDisplayName';
HigherOrderComponent.displayName = wrapDisplayName(BaseComponent, 'HigherOrderComponent');

Сценарии применения компонентов высшего порядка

Не говорить о технологии сцены — значит хулиганить, поэтому поговорим о том, как использовать высокоуровневые компоненты в бизнес-сценариях.

Контроль доступа

с использованием компонентов более высокого порядкаусловный рендерингФункции могут управлять разрешениями на страницах. Управление разрешениями обычно делится на два аспекта:уровень страницыиуровень элемента страницы, вот каштан на уровне страницы:

// HOC.js
function withAdminAuth(WrappedComponent) {
    return class extends React.Component {
        state = {
            isAdmin: false,
        }
        async componentWillMount() {
            const currentRole = await getCurrentUserRole();
            this.setState({
                isAdmin: currentRole === 'Admin',
            });
        }
        render() {
            if (this.state.isAdmin) {
                return <WrappedComponent {...this.props} />;
            } else {
                return (<div>您没有权限查看该页面,请联系管理员!</div>);
            }
        }
    };
}

Затем две страницы:

// pages/page-a.js
class PageA extends React.Component {
    constructor(props) {
        super(props);
        // something here...
    }
    componentWillMount() {
        // fetching data
    }
    render() {
        // render page with data
    }
}
export default withAdminAuth(PageA);

// pages/page-b.js
class PageB extends React.Component {
    constructor(props) {
        super(props);
        // something here...
    }
    componentWillMount() {
        // fetching data
    }
    render() {
        // render page with data
    }
}
export default withAdminAuth(PageB);

После повторного использования кода с высокоуровневыми компонентами его можно легко расширить.Например, менеджер продукта сказал, что страница PageC должна иметь права администратора для входа, нам нужно толькоpages/page-c.jsВложите возвращенный PageC на один уровеньwithAdminAuthПодойдет компонент более высокого порядка, напримерwithAdminAuth(PageC). Разве это не прекрасно! Очень эффективный! ! но. . На следующий день менеджер по продукту сказал, что доступ к странице PageC возможен только с привилегиями VIP. Вы реализуете компонент более высокого порядкаwithVIPAuth. День третий. . .

На самом деле можно и эффективнее, то есть абстрагировать слой поверх высокоуровневых компонентов, не внедряя различныеwithXXXAuthКомпоненты более высокого порядка, потому что сами эти компоненты более высокого порядка очень похожи по коду, поэтому нам нужно реализоватьФункция, которая возвращает компонент более высокого порядка,ПучокИзмененная часть (Админ, VIP)снять, сохранитьпостоянная часть, конкретная реализация выглядит следующим образом:

// HOC.js
const withAuth = role => WrappedComponent => {
    return class extends React.Component {
        state = {
            permission: false,
        }
        async componentWillMount() {
            const currentRole = await getCurrentUserRole();
            this.setState({
                permission: currentRole === role,
            });
        }
        render() {
            if (this.state.permission) {
                return <WrappedComponent {...this.props} />;
            } else {
                return (<div>您没有权限查看该页面,请联系管理员!</div>);
            }
        }
    };
}

Можно обнаружить, что после слоя абстракции высокоуровневых компонентов предыдущийwithAdminAuthможно записать какwithAuth('Admin'), если вам нужен VIP-доступ в это время, просто перейдите наwithAuthпередается в функцию'VIP'Вот и все.

Вы нашли иreact-reduxизconnectМетод используется очень похожим образом? Верно,connectНа самом делеФункция, которая возвращает компонент более высокого порядка.

Отслеживание производительности рендеринга компонентов

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

class Home extends React.Component {
    render() {
        return (<h1>Hello World.</h1>);
    }
}
function withTiming(WrappedComponent) {
    return class extends WrappedComponent {
        constructor(props) {
            super(props);
            this.start = 0;
            this.end = 0;
        }
        componentWillMount() {
            super.componentWillMount && super.componentWillMount();
            this.start = Date.now();
        }
        componentDidMount() {
            super.componentDidMount && super.componentDidMount();
            this.end = Date.now();
            console.log(`${WrappedComponent.name} 组件渲染时间为 ${this.end - this.start} ms`);
        }
        render() {
            return super.render();
        }
    };
}

export default withTiming(Home);

withTiming

withTimingэто использоватьобратное наследованиеРеализован компонент более высокого порядка, функция состоит в том, чтобы вычислить обернутый компонент (вотHomeкомпонент) время рендеринга.

повторное использование страницы

Предположим, у нас есть две страницыpageAиpageBВизуализируйте две категории списков фильмов отдельно, обычное написание может быть таким:

// pages/page-a.js
class PageA extends React.Component {
    state = {
        movies: [],
    }
    // ...
    async componentWillMount() {
        const movies = await fetchMoviesByType('science-fiction');
        this.setState({
            movies,
        });
    }
    render() {
        return <MovieList movies={this.state.movies} />
    }
}
export default PageA;

// pages/page-b.js
class PageB extends React.Component {
    state = {
        movies: [],
    }
    // ...
    async componentWillMount() {
        const movies = await fetchMoviesByType('action');
        this.setState({
            movies,
        });
    }
    render() {
        return <MovieList movies={this.state.movies} />
    }
}
export default PageB;

Когда несколько страниц могут быть не проблемой, но если с развитием бизнеса вам нужно все больше и больше типов фильмов в сети, это будет писать много дублирования кода, поэтому нам нужно провести рефакторинг:

const withFetching = fetching => WrappedComponent => {
    return class extends React.Component {
        state = {
            data: [],
        }
        async componentWillMount() {
            const data = await fetching();
            this.setState({
                data,
            });
        }
        render() {
            return <WrappedComponent data={this.state.data} {...this.props} />;
        }
    }
}

// pages/page-a.js
export default withFetching(fetching('science-fiction'))(MovieList);
// pages/page-b.js
export default withFetching(fetching('action'))(MovieList);
// pages/page-other.js
export default withFetching(fetching('some-other-type'))(MovieList);

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

Шаблон декоратора? Компоненты высшего порядка? АОП?

Как вы могли заметить, компоненты более высокого порядка на самом деле являются реализацией шаблона декоратора в React: при передаче компонента (функции или класса) в функцию функция компонента (функции или класса) улучшается внутри функции ( не на предпосылке изменения входящих параметров), и, наконец, вернуть компонент (функцию или класс), что позволяет добавлять новые функции к существующему компоненту без изменения компонента, принадлежащегоШаблон оберткитипа.

Что такое шаблон декоратора:Динамически добавлять некоторые дополнительные свойства или поведение к объекту во время выполнения программы, не изменяя сам объект..

Шаблон декоратора является более легким и гибким подходом, чем использование наследования.

Реализовано с помощью шаблона декоратораAOP:

Аспектно-ориентированное программирование (АОП), как и объектно-ориентированное программирование (ООП), является просто парадигмой программирования и не определяет, как реализовать АОП.

// 在需要执行的函数之前执行某个新添加的功能函数
Function.prototype.before = function(before = () => {}) {
    return () => {
        before.apply(this, arguments);
        return this.apply(this, arguments);
    };
}
// 在需要执行的函数之后执行某个新添加的功能函数
Function.prototype.after = function(after = () => {}) {
    return () => {
        this.apply(this, arguments);
        return after.apply(this, arguments);
    };
}

можно найти на самом делеbeforeиafterтолько одинФункции высшего порядка, очень похоже на компоненты более высокого порядка.

Аспектно-ориентированное программирование (AOP) в основном используются вФункции, не связанные с основным бизнесом, но используемые в нескольких модулях, таких как контроль разрешений, ведение журнала, проверка данных, обработка исключений, статистическая отчетность и т. д..

АналогияAOPВы уже должны знать, с какими проблемами обычно справляются компоненты более высокого порядка.

Суммировать

в реакциикомпоненты более высокого порядкаНа самом деле, это очень простая концепция, но очень практичная. Разумное использование компонентов более высокого порядка в реальных бизнес-сценариях,Может улучшить повторное использование кода и гибкость.

Наконец, небольшое резюме компонентов более высокого порядка:

  • компоненты более высокого порядкане компонент,даТот, который преобразует один компонент в другойфункция
  • Основная роль компонентов высшего порядка состоит в том, чтобыповторное использование кода
  • Компоненты более высокого порядкаРеализация шаблона декоратора в React

follow

Для получения дополнительных галантерейных товаров, пожалуйста, обратите внимание на общедоступную учетную запись «Маленькая колонка переднего плана: QianDuanXiaoZhuanLan».