Реагировать отложить рендеринг до async componentDidMount

Я заполняю свое состояние асинхронным вызовом внутри componentDidMount. Если выборка не удалась, я хочу перенаправить пользователя. Перенаправление выполняется с помощью компонента <PageNotFound />. Увидеть ниже:

class Product extends React.Component {
  constructor(props) {
    super(props);
  }

 componentDidMount() {
    getProduct(this.props.productId).then(product =>
      this.setState({ product })
    );
  }

 render() {
    return this.state.product ? (
      <ProductView product = {product}/>
    ) : (
      <PageNotFound />
    );
  }
}

Проблема в том, что React запускает метод render() до завершения асинхронного вызова. Это приводит к перенаправлению пользователя до завершения асинхронного вызова. Единственное исправление, которое я вижу, - это добавление дополнительного флага isLoading в состояние, но мне интересно, есть ли другое обходное решение для этого.

Возможно, вам понадобится индикатор загрузки.

TrueWill 29.11.2018 19:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
326
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

  • На этапе загрузки
  • После фазы выборки - ProductView
  • После фазы выборки - перенаправление

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

Хорошие моменты. Мне было любопытно, есть ли в React встроенный способ отложить рендеринг, но теперь я думаю, что этот метод в любом случае имеет больше смысла. Спасибо!

tallpaulk 29.11.2018 19:53

Ответ предложил Ишвар

class Product extends React.Component {
  constructor(props) {
    super(props);
    this.state = { fetchingProduct: true }
  }

  componentDidMount() {
    getProduct(this.props.productId)
      .then(product => this.setState({ product, fetchingProduct: false }))
      .catch(() => this.setState({ fetchingProduct: false }))
  }

  render() {
    return fetchingProduct ? (
      this.state.product ? (
          <ProductView product = {product}/>
      ) : (
          <PageNotFound />
      )
    ) : (
        <LoadingComponent />
    )
  }
}

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