Распространение реквизитов в компонентах React более высокого порядка

#javascript #reactjs #higher-order-functions #higher-order-components

#javascript #reactjs #функции более высокого порядка #компоненты более высокого порядка

Вопрос:

Я пытаюсь углубиться, чтобы понять цель распространения реквизита в React HOC

Итак, взяв приведенный ниже пример;

 const EnhanceComponent = BaseComponent => {
    return class EnhancedComponent extends Component {
        state = {
            name: 'You have been enhanced'
        }
        render() {
           return ( 
           <BaseComponent {...this.props} {...this.state} />   
        )
       }
    }
};

export default EnhanceComponent;
 

Теперь предположим, что использование BaseComponent выглядит следующим образом;

 <BaseComponent className='wrapper-container' onClick={this.handleClick} />
 

Я предполагаю, что если бы не распространение реквизита в HOC, мы не смогли бы получить доступ к «this.props.className» ИЛИ «this.props.onClick» в BaseComponent. Будет ли это правильным пониманием?

 class BaseComponent extends React.Component {
      render() {
         const { className, onClick} = this.props;

         ...
      }
   }
 

Теперь, чтобы использовать сам HOC, мы бы сказали;

 const EnhancedMyComponent = EnhanceComponent(MyComponent);
 

И визуализируйте его как

 <EnhancedMyComponent className='wrapper-container' onClick={this.handleClick} />
 

Теперь, ниже приведены мои 2 конкретных вопроса;

  1. Что мы в конечном итоге визуализируем, т.Е. BaseComponent или EnhancedMyComponent ИЛИ использование HOC позволяет нам использовать любой вариант, например. в каком-то случае, если мы не хотим расширенной функциональности, мы просто используем базовый компонент?

или

 <EnhancedMyComponent className='wrapper-container' onClick={this.handleClick} />
 
  1. Будет ли проблема с доступом к реквизиту, т.Е. Если мы не распространим реквизит, применима в обоих вышеуказанных случаях потребления, т.Е. <BaseComponent /> И <EnhancedMyComponent /> ?

Ответ №1:

1) Что мы в конечном итоге визуализируем, т.Е. BaseComponent или EnhancedMyComponent ИЛИ использование HOC позволяет нам использовать любой вариант, например. в каком-то случае, если мы не хотим расширенной функциональности, мы просто используем базовый компонент?

/ Использование HOC позволяет нам использовать любой вариант. Это полностью зависит от того, где мы оборачиваем компонент в HOC, т.е. При экспорте или при его использовании где-либо.

Теперь, в приведенном ниже случае, у вас есть возможность использовать его с HOC или без него

 // BaseComponent.js 
        class BaseComponent extends React.Component {
                  render() {
                     const { className, onClick} = this.props;
            
                     ...
                  }
               }
    export default BaseComponent;
    
    // SomeComponent.js
    import BaseComponent from './BaseComponent';

    const MyComponent = EnhanceComponent(BaseComponent);
    class SomeComponent extends React.Component {
                  render() {
                     return ( 
                     ...
                     <MyComponent className={...} onClick={...} someExtraPropForHOC={...}/>
                     <BaseComponent  className={...} onClick={...} />
                     ...
                  )
               }
 

Чтобы никто не мог напрямую использовать компонент, оберните его в HOC и экспортируйте

 // BaseComponent.js 
    class BaseComponent extends React.Component {
              render() {
                 const { className, onClick} = this.props;
        
                 ...
              }
           }
export default EnhanceComponent(BaseComponent);

// SomeComponent.js
import BaseComponent from './BaseComponent';
class SomeComponent extends React.Component {
              render() {
                 return ( 
                 ...
                 <BaseComponent className={...} onClick={...}/>
                 ...
              )
           }
 

2) Будет ли проблема с доступом к реквизиту, т.Е. Если мы не распространим реквизит, применима в обоих вышеуказанных случаях потребления, т.Е. И ?

/ Распространение реквизита необходимо, поскольку HOC не знает, какие реквизиты понадобятся для динамически обернутого компонента. Поэтому передача всех реквизитов, которые поступают, является единственно возможным способом.

 class BaseComponent extends React.Component {
      render() {
         const { className, onClick} = this.props;

         ...
      }
   }

class CustomTextField extends React.Component {
      render() {
         const { className, onKeyPress, value} = this.props;

         ...
      }
   }

const EnhancedBaseComponent = EnhanceComponent(BaseComponent);
const EnhancedTextComponent = EnhanceComponent(CustomTextField);
 

Теперь в этом случае EnhancedBaseComponent и EnhancedTextComponent обоим нужны разные реквизиты, но поскольку они завернуты в EnhanceComponent . Он не будет знать, какие реквизиты передавать. Так что распространяйте его и отправляйте все реквизиты, поступающие к нему.

Комментарии:

1. Большое спасибо… Вы довольно близки к тому, что я ищу… единственное, что касается (1), было бы действительно здорово, если бы вы могли добавить некоторый скелетный код для обоих случаев, чтобы мне было понятнее.

2. Ты потрясающий …. Продолжение… Для 2-го варианта, где вы говорите (чтобы не позволять никому напрямую использовать компонент, оберните его в HOC и экспортируйте) Я вижу, вы выполнили экспорт компонента расширения по умолчанию (BaseComponent); Однако при использовании я вижу, что вы использовали BaseComponent . Я что-то здесь упускаю? <Имя_класса базового компонента={…} onClick={…}/>

3. Спасибо. При импорте я использовал само имя файла BaseComponent. Его можно назвать как угодно. Поскольку мы импортируем компонент, не зная, как он экспортируется. Мы ожидаем, что он будет базовым компонентом при импорте, не зная внутреннего экспорта.

4. О k…So на самом деле это компонент EnhanceComponent(BaseComponent), который импортируется и используется в этом случае, и мы напрямую не используем / не используем класс компонента BaseComponent Правильно?