Компонент не выполняет повторный рендеринг при изменении URL

#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 будет запущена после того, как рендеринг будет зафиксирован на экране.