Реагирует ли экран загрузки на все маршруты? - PullRequest
0 голосов
/ 16 сентября 2018

Я понимаю, как я могу получить вращающийся экран с state и componentDidMount(), но как мне создать промежуточный экран загрузки на всех маршрутах без необходимости писать componentDidMount() в каждом компоненте?

Мой файл app.js

class App extends Component {

  constructor(props) {
    super(props);
    this.child = React.createRef();
  }

  onWaypoint = () => {
    this.child.current.navChangeHandler();
  }

  render() {

    let routes = (
      <Switch>    
        <Route exact path="/projects" component={Projects} />
        <Route exact path="/about" component={About} />
        <Route exact path="/gallery" component={Gallery} />
        <Route exact path="/" component={Home} />
        <Redirect exact to="/" />
      </Switch>
    )

    return (
      <BrowserRouter>
        <div className="App" styleName="main-wrapper">
          <Layout>
              {routes}
              <Navigation ref={this.child} />
          </Layout>
        </div>
      </BrowserRouter>

    );
  }
}

Я хочу, чтобы между этими маршрутами можно было видеть вертушку.

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

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

Разделение кода в React с использованием ReactЗагружаемый

Разделение кода с помощью React и React Router

0 голосов
/ 16 сентября 2018

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

Например:

Parent:

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.setState({ isLoading: true });
      }
    };

    doneLoading = () => this.setState({ isLoading: false })

    render = () => (
      <WrappedComponent
        doneLoading={this.doneLoading}
        isLoading={this.state.isLoading}
        {...this.props}
      />
    );
  }
  return withRouter(Wrapper);
};

Дочерний (имеет доступ к переданному методу / состоянию HOC изнутри дочернего this.props):

export default class Child extends PureComponent {

  componentDidMount = () => {
    fetch("someURL")
      .then(response => response.json())
      .then(json => this.setState({ list: json }), () => this.props.doneLoading());
  };

  render = () =>
    this.props.isLoading 
      ? <Spinner />
      : <DisplayList list={...this.state.list} />
}

Недостатком является то, что каждый дочерний компонент должен импортировать Spinner и убедитесь, что isLoading неверно.

Ограничения

Для того, чтобы это работало среди сильно вложенных компонентов, вам, скорее всего, понадобится / нужно будет интегрировать Redux.Кроме того, вам нужно, чтобы подключенный контейнер отправлял действие для обновления / сброса состояния isLoading Redux при каждом изменении маршрута.В любом случае, это не будет простым и элегантным решением, если вы хотите быть СУХИМЫМ.


Пример

Рабочий пример (в этом примере просто установлено / не установлено состояние HOC)по таймауту): https://codesandbox.io/s/2zo8lj44pr

Wrapper.js

import React, { Component, Fragment } from "react";
import { withRouter } from "react-router";
import Header from "./Header";
import Spinner from "./Spinner";

export default WrappedComponent => {
  class Wrapper extends Component {
    state = { isLoading: true };

    componentDidMount = () => this.setTimer();

    componentDidUpdate = prevProps => {
      if (this.props.location !== prevProps.location) {
        this.clearTimer();
        this.setState({ isLoading: true }, () => this.setTimer());
      }
    };

    clearTimer = () => clearTimeout(this.timeout);

    timer = () => this.setState({ isLoading: false }, () => this.clearTimer());

    setTimer = () => (this.timeout = setTimeout(this.timer, 3000));

    render = () => (
      <Fragment>
        <Header />
        {this.state.isLoading
          ? <Spinner />
          : <WrappedComponent {...this.props} />
      </Fragment>
    );
  }
  return withRouter(Wrapper);
};

index.js

import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Home from "../components/Home";
import Schedule from "../components/Schedule";
import Wrapper from "./components/Wrapper";

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Wrapper(Home)} />
      <Route path="/schedule" component={Wrapper(Schedule)} />
    </Switch>
  </BrowserRouter>,
  document.getElementById("root")
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...