Я заполняю свое состояние асинхронным вызовом внутри 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 в состояние, но мне интересно, есть ли другое обходное решение для этого.





Флаг загрузки - правильный путь. Подумайте об этом с точки зрения пользователя. Что должен видеть пользователь, пока не будет выполнен асинхронный вызов. Что бы это ни было, должно быть отрисовано на этапе выборки. Следовательно, есть три возможности для пользовательского интерфейса компонента:
Итак, да, вам нужно добавить еще один флаг, чтобы поддерживать более двух состояний.
Хорошие моменты. Мне было любопытно, есть ли в React встроенный способ отложить рендеринг, но теперь я думаю, что этот метод в любом случае имеет больше смысла. Спасибо!
Ответ предложил Ишвар
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 />
)
}
}
Возможно, вам понадобится индикатор загрузки.