Создание компонента React более высокого порядка для использования в качестве оболочки-загрузчика (анимации) для дочерних компонентов. - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть много компонентов, которые требуют отправки некоторой функции ajax в методе componentDidMount. Я хотел бы создать HOC, единственная цель которого - «применить» некоторую анимацию к компоненту и остановить эту анимацию, как только определенное обещание будет выполнено.

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

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

componentDidMount() {
ajax('/costumers')
  .then(({ data }) => {
    this.setState(() => ({ costumers: data.content }))
  })
}

Технически, мне нужно либо передать эту функцию в качестве аргумента в HOC, либо, возможно, каким-то образом «похитить» дочерний componentDidMount (если что-то подобное возможно ...). После этого HOC будет применять анимацию после загрузки, а затем отправлять ajax, и только после ее устранения анимация удаляется, а дочерний компонент обрабатывается.

Как этого достичь?

Любая идея будет оценена

1 Ответ

0 голосов
/ 27 апреля 2018

Вот как вы можете написать HOC для такого случая, см. React docs для получения дополнительной информации по теме.

const withLoader = (loader, Component) =>
  class WithLoader extends React.Component {
    state = { ready: false, data: null };

    async componentDidMount() {
      const data = await loader();

      this.setState({ ready: true, data });
    }

    render() {
      if (!this.state.ready) return <div>LOADING</div>; // or <ComponentWithAnimation />

      return <Component data={this.state.data} />;
    }
  };

const Test = props => <div>DATA: {props.data}</div>;

const fakeLoader = () =>
  new Promise(res => setTimeout(() => res("My data"), 1000));

const TestWithLoader = withLoader(fakeLoader, Test);
...