Пропуск реквизита в HOC

Есть необычный вопрос об исключении реквизита в HoC

У меня есть компонент реакции:

interface IMyComponentProps {
  prop1: string,
  prop2: Function,
  items1: string[],
  items2: string[],
}

и у меня есть HOC, который берет этот компонент и передает ему элементы1 и элементы2

interface IWithItems {
  items1: string[],
  items2: string[],
}

type WithoutItems<T extends IWithItems> = Omit<T, 'items1'|'items2'>;


function HoC<T extends IWithItems>(
  WrappedComponent:
    React.ComponentClass<T>
    | React.FunctionComponent<T>,
): React.ComponentClass<WithoutItems<T>> {
  class WithItemsWrapper extends React.Component<WithoutItems<T>, IWithItems> {

    state = {
      items1: [],
      items2: [],
    };

    async componentDidMount() {
      const items1 = await this.getItems1();
      const items2 = await this.getItems2();

      this.setState({
        items1,
        items2,
      });
    }

    getItems1 = () => (
      // from backend
    );

    getItems2 = () => (
      // from backend
    );

    render() {
      return (
        <WrappedComponent
          {...this.props}
          items1 = {this.state.items1}
          items2 = {this.state.items2}
        />
      );
    }
  }

  return hoistNonReactStatics(WithItemsWrapper, WrappedComponent);
}

Обернутый компонент имеет собственные реквизиты, и эти реквизиты содержат элементы1, элементы2. HoC извлекает элементы из бэкэнда и передает их обернутому компоненту

в моем файле index.ts я экспортирую его как

export default HoC(MyComponent);

идея в том, что после этого экспорта и импорта этого в другой файл MyComponent должны требоваться prop1 и prop2, но не items1 и items2, потому что они уже прошли в HoC.

Но теперь он говорит

Error:(59, 12) TS2322: Type 'Readonly<Pick<T, Exclude<keyof T, "items1" | "items2">>> & { items1: never[]; items2: never[]; children?: ReactNode; }' is not assignable to type 'IntrinsicAttributes & T & { children?: ReactNode; }'.
  Type 'Readonly<Pick<T, Exclude<keyof T, "items1" | "items2">>> & { items1: never[]; items2: never[]; children?: ReactNode; }' is not assignable to type 'T'.

Возможно ли это, и если да, то что я делаю не так?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
561
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы поступили наоборот. HoC принимает компонент с items1 и items2 и возвращает HOC без items1 и items2. Итак, для компонента

let ResultingComponent = HoC(MyComponent);

вы должны предоставить только prop1 и prop2. items1 и items2 будут заполнены из HoC.

Если вы хотите передать компонент без items1 и items2, но получившийся компонент содержит items1 и items2, вы должны сделать так:

function HoC<T>(
    WrappedComponent:
        React.ComponentClass<T>
        | React.FunctionComponent<T>,
): React.ComponentClass<T & IWithItems> {
    class WithItemsWrapper extends React.Component<T & IWithItems, IWithItems> {

        render() {
            return (
                <>
                // Do some rendering based on this.props.items1 and this.props.items2
                    <div>{this.props.items1.map(e => (<div>{e}</div>))}</div>
                    <WrappedComponent
                        {...this.props}
                    />
                </>
            );
        }
    }

    return hoistNonReactStatics(WithItemsWrapper, WrappedComponent);
}

Но обратите внимание, что в этом случае item1 и item2 должны быть предоставлены результирующему компоненту из HoC. Внутри HoC вы не должны получать эти пропсы от бэкенда, но вы должны рендерить что-то на основе этих пропсов и не передавать их в WrappedComponent.

спасибо за ваш ответ, но я думаю, что это не совсем то, что я ищу. Компонент должен ожидать элементы 1 и элементы 2 на основе его интерфейса. Но я пытаюсь разделить выборку данных из бэкэнда в HOC, чтобы упростить тестирование компонента. идея в том, что я могу импортировать компонент и передавать эти два реквизита из любого места, но если я не хочу этого делать, я могу импортировать компонент, обернутый этим HOC, и заставить его работать сам по себе. цель - реквизиты items1 и items2 должны существовать в компоненте, но когда он обернут HOC, их не должно быть, потому что они перешли из HOC. Может я плохо мыслю?

Prvz 03.07.2019 15:16
Ответ принят как подходящий

кажется я нашел решение

Прежде всего упростите WithoutItems и измените определение HOC.

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
type Diff<T, K> = Omit<T, keyof K>;

type WithoutItems<T> = Diff<T, IWithItems>;

function HoC<P>(
  WrappedComponent:
    React.ComponentClass<P>
    | React.FunctionComponent<P>,
): React.ComponentClass<WithoutItems<P>> {
  class WithItemsWrapper extends React.Component<WithoutItems<P>, IWithItems> {

и следующее, что нужно сделать, это сделать карту реквизита явно типом P

// HoC render method
  render() {
    return (
      <WrappedComponent
        {...this.props as P}
        items1 = {this.state.items1}
        items2 = {this.state.items2}
      />
    );
  }

все остальное остается как было.


решение найдено здесь

Другие вопросы по теме