#reactjs #react-hooks #react-router-dom
#reactjs #реагирующие хуки #react-router-dom
Вопрос:
Router
Конфигурация выглядит следующим образом
App.js
<Router>
<Switch>
<Route exact path="/" render={() => <Home />} />
<Route exact path="/products/:productId" component={ ProductDetail } />
<Redirect to="/" />
</Switch>
</Router>
Вот как ProductDetail
выглядит компонент
ProductDetail.js
export const ProductDetail = ({ match }) => {
const productId = match.params.productId;
useEffect(() => {
dispatch(fetchProductById(productId));
}, [productId, dispatch]);
const product = useSelector((state) => selectProductById(state, productId));
return(<.....>)
}
Теперь, когда я перехожу от Home
к ProductDetail
, все работает нормально. Однако, если я попытаюсь напрямую перейти по URL http://localhost:3000/products/someId
-адресу, компонент не будет отображаться, и useEffect
перехват не вызывается.
Я прочитал Router
документацию, и в ней говорится
Когда вы используете component (вместо render или дочерних элементов, ниже), маршрутизатор использует React.createElement для создания нового элемента React из данного компонента.
Разве это не должно означать, что вновь созданный компонент ( ProductDetail
в моем случае) должен отображаться, а хуки вызываются? Я новичок React
, поэтому, возможно, мне не хватает чего-то довольно простого.
Комментарии:
1.
Home
Инициализирует ли компонент какое-то состояние, от которогоProductDetail
зависит? Под «компонент не рендерится» вы подразумеваете, что он рендеритHome
компонент или что он вообще ничего не рендерит?2. Да,
Home
компонент такжеuseEffect(async func...)
имеет, и он предварительно выбирает продукты для домашней страницы. ТеперьProductDetail
нужно просто показать детали для отдельного продукта. Под «component does not rendering» я подразумеваю, что компонент ProductDetails прерывается, если я напрямую нажимаю на URL с помощьюproductId
3. Что вы подразумеваете под «перерывами»? Есть ли ошибка?
4. Сообщение об ошибке означает
can't read property title of undefined
, что не извлекается продукт, для которого он пытается выполнить рендерингproduct.title
5. Перехваты запускаются при рендеринге компонента. Компонент не ожидает результата действия.
Ответ №1:
Как упоминалось в комментариях, продукт еще не будет в магазине при непосредственном переходе к ProductDetail
компоненту. useEffect
Перехват инициирует загрузку продукта, но до тех пор, пока это не закончится, product
будет неопределенным (или нулевым, или что-то еще, в зависимости от вашего редуктора). Вам нужно будет обработать этот случай отдельно.
Самый простой способ справиться с этим — отобразить какой-либо индикатор загрузки, например
export const ProductDetail = ({ match }) => {
const productId = match.params.productId;
useEffect(() => {
dispatch(fetchProductById(productId));
}, [productId, dispatch]);
const product = useSelector((state) => selectProductById(state, productId));
if (!product) {
return <p>Loading...</p>
}
return(<.....>)
}
Кроме того, как также упоминалось в комментариях, при рендеринге компонента обычно срабатывают перехваты. Компонент не ожидает завершения действия, инициированного useEffect
перехватчиком. Из документов React:
Переданная функция
useEffect
будет запущена после того, как рендеринг будет зафиксирован на экране.