Как я могу избежать ненужного повторного рендеринга компонента HOC, когда компонент параметра отображается в ReactJS с реагирующим маршрутизатором

Я использую HOC (здесь компонент макета), чтобы обернуть свой пользовательский компонент. Компонент макета содержит заголовок и боковую панель. При нажатии на ссылку будет отображаться соответствующий компонент. Но моя проблема в том, что с каждым маршрутом мой HOC отображается, поскольку целевой компонент маршрута завернут в этот HOC. Как я могу сделать рендеринг HOC только один раз. Фрагмент примера.

App.js

<Router>
<Switch>

<PrivateRoute path="routeOne" component={RouteOne}/>
<PrivateRoute path="routeTwo" component={RouteTwo}/>

</Switch>
</Router>

RouteOne.js

import React from "react"
import Layout from "/hoc"
const RouteOne  = () =>{
return({..jsx..})
}
export default Layout(RouteOne)

Layout.js

const Layout(WrappedComponent) => {
 const userDetails = useSelector(state);
 useEffect(()=>{
 dispatch(fetchSomething())
        },[dispatch])
    

 return ( <HeaderNavbarUILayout header={<Header 
 username={userDetails.userName}> 
 content={<WrappedComponent/>);
                }
export default Layout

Я хочу визуализировать свой компонент HOC только один раз. Как я могу это сделать?


person user8715552    schedule 20.06.2020    source источник
comment
пробовали иметь const Layout = WrappedComponent => React.memo(() => {...}) ?   -  person Marouane Fazouane    schedule 21.06.2020
comment
@MarouaneFazouane Я пробовал это, но кажется, что это усложняет компонент. Также на странице есть диспетчеры действий и селекторы избыточности, что также вызывает некоторые синтаксические ошибки.   -  person user8715552    schedule 22.06.2020


Ответы (2)


РЕДАКТИРОВАТЬ: я бы следовал этому шаблону https://simonsmith.io/reusing-layouts-in-react-router-4

const DefaultLayout = ({component: Component, ...rest}) => {
  return (
    <Route {...rest} render={matchProps => (
      <div className="DefaultLayout">
        <div className="Header">Header</div>
          <Component {...matchProps} />
        <div className="Footer">Footer</div>
      </div>
    )} />
  )
};

то там, где вы обычно определяете маршруты, замените его следующим:

<DefaultLayout path="/" component={SomeComponent} />

Я бы посмотрел на следующие документы:

как использовать useEffect

https://reactjs.org/docs/hooks-reference.html#useeffect

как реализовать обновление компонента

https://reactjs.org/docs/hooks-faq.html#how-do-i-i-implement-shouldcomponentupdate

условное срабатывание эффекта

```
useEffect(
  () => {
    ...
    };
  },
  [whatever you're watching],
);
```
person c0de    schedule 21.06.2020
comment
Вместе с тем, будучи начинающим React-разработчиком, я хотел бы знать, был ли мой подход правильным. Компоненты макета не должны перерисовываться при каждом изменении маршрута. В то же время я хочу повторно использовать компонент макета, чтобы обернуть свой компонент функции, поэтому я сделал его HOC. - person user8715552; 21.06.2020
comment
было бы очень полезно, если бы вы могли поделиться минимальным воспроизводимым примером. некоторые вопросы, которые приходят на ум, вы подтвердили, что ваш макет перерисовывается при изменении маршрута? в качестве альтернативы я нашел шаблон, который кажется довольно разумным и решает вашу проблему simonsmith. io/reusing-layouts-in-react-router-4 - person c0de; 21.06.2020
comment
Спасибо, что предложили мне эту ссылку. Но разница здесь в том, что я использую hoc для компонента Layout. пример: const userProfile = ()=›{ ... } export Layout(userProfile) Таким образом, профиль пользователя входит в содержимое внутри макета. Чтобы ответить на ваш вопрос, да, я подтвердил повторный рендеринг, поместив журнал консоли. Кроме того, при каждом изменении маршрута экран, кажется, обновляется, подтверждая это. В useEffect() я также отправляю действие для загрузки информации о пользователе, также я попытаюсь отредактировать свой вопрос, указав дополнительную информацию. - person user8715552; 21.06.2020
comment
кажется, что вы связываете макет с вещами, специфичными для HOC. Не могли бы вы разъединить и следовать шаблону «повторного использования макетов», который обслуживает ваш упакованный компонент HOC? - person c0de; 21.06.2020

Hoc, обернутый вокруг, отображается каждый раз, и это ожидается. Но алгоритм сравнения React будет отображать только измененные элементы DOM. Проблема здесь заключалась в том, что диспетчер вызывается каждый раз, когда отображается страница макета, и состояние обновляется, и, следовательно, обновляется конкретный DOM. Это создает впечатление эффекта перезагрузки. Условная отправка действия поможет. Отправка только при изменении состояния.

person user8715552    schedule 24.06.2020