Когда я переключаюсь между вложенными маршрутами (подпрограммами) с помощью «Ссылки», родительский компонент отключается. Есть ли какой-нибудь способ избежать этого?

#reactjs #react-router-dom

Вопрос:

Обновлено: В этом коде есть проблема. Я ответил ниже

Это мой внешний компонент «Приложение». В этом у меня есть маршрут компонента «Панель мониторинга»

 export default function App() {
  return (
    <Router>
      <div>
        <hr />

        <Switch>
          <Route exact path="/">
            <Redirect to="/dashboard" />
          </Route>
          <Route path="/dashboard" component={Dashboard} />
          <Route path="*" component={() => <h1>not found</h1>} />
        </Switch>
      </div>
    </Router>
  );
}
 

Компонент «Панель мониторинга», содержащий вложенные маршруты к компонентам «Главная страница» и «Чат»

 function Dashboard({ match }) {
  useEffect(() => {
    console.log("dashboard mounted");
    return () => console.log("dashboard unmounted");
  });
  return (
    <div>
      <Switch>
        <Route exact path={`${match.path}`} component={Home} />
        <Route exact path={`${match.path}/chat`} component={Chat} />
      </Switch>
    </div>
  );
}
 

Компонент «Главная страница» и «Чат»

 function Home({ match }) {
  useEffect(() => {
    console.log("home mounted");
    return () => console.log("home unmounted");
  });
  return (
    <div>
      <h3>home component</h3>
      <Link to={`${match.url}/chat`}>
        <button>chat</button>
      </Link>
    </div>
  );
}

function Chat() {
  useEffect(() => {
    console.log("chat mounted");
    return () => console.log("chat unmounted");
  });
  return (
    <div>
      <h3>Chat component</h3>
    </div>
  );
}
 

Проблема в том, что когда я перехожу из «Дома» в «Чат», компонент «Панель мониторинга» (родительский) отключается. Я хочу избежать этого

CodeSandbox

проверьте консоль

Комментарии:

1. И почему именно вы хотите избежать размонтирования Dashboard компонента? react-router-dom работает таким образом, поэтому, если вы заставляете его отклоняться от его правильной функциональности, это может привести к неожиданному поведению. Чего именно вы пытаетесь достичь, не могли бы вы рассказать нам больше? Вероятно, есть другой способ решить вашу проблему

2. Привет @Kapobajza, но если у нас глубоко вложенная архитектура маршрута, и я просто хочу перейти к вложенному маршруту на том же уровне, то это вызовет проблемы с производительностью, так как вся древовидная структура будет перезагружена. Я думаю, что в Angular мы можем переключаться между вложенными компонентами без перезагрузки родительского компонента

3. Привет @Kapobajza, На самом деле я хочу получить общие данные в компоненте «Панель мониторинга», которые будут использоваться вложенными компонентами, и добавить прослушиватели событий сокетов в мой компонент «Панель мониторинга». В то же время сведите мой компонент «Приложение» к минимуму. вы можете помочь ?

4. Вам обязательно доставать его в Dashboard компоненте? Не могли бы вы просто извлечь эти общие данные из App компонента?

5. Хорошо бы сохранить логику вне «приложения». Также у моего кода есть проблема. Маршрутизатор React не размонтирует родительский компонент (панель мониторинга). Я ответил ниже.

Ответ №1:

Вы не можете вложить разные <Switch /> теги.

 export default function App() {

useEffect(() => {
   console.log("app mounted");
   return () => console.log("app unmounted");
});

return (
  <Router>
    <div>
      <hr />

      <Switch>
        <Route exact path="/">
          <Redirect to="/dashboard" />
        </Route>
        <Route path="/dashboard/chat" component={Chat} />
        <Route path="/dashboard" component={Home} />
        <Route path="*" component={() => <h1>not found</h1>} />
      </Switch>
    </div>
  </Router>
);

}
 

Комментарии:

1. Извините, но я не мог понять, что вы пытаетесь сказать. Не могли бы вы, пожалуйста, объяснить подробнее?

2. Внутри вашего Dashboard тега у вас есть еще <Switch /> один, и маршрутизатор не может обрабатывать несколько вложенных тегов коммутатора. Поэтому, если вы хотите сохранить свое родительское состояние, не размонтируя его, вам необходимо удалить вложенный тег переключателя. Это позволяет использовать только один переключатель для обработки всех маршрутов и предотвращения отключения родительского устройства

3. но даже если я удалю вложенные теги <Switch/>, компонент «Панель мониторинга» отключится.

Ответ №2:

В моем приведенном выше коде есть проблема. На самом деле маршрутизатор React не размонтирует родительский компонент, если есть вложенные маршруты, и мы переключаемся между ними. . Я забыл добавить пустой массив зависимостей в «Панель мониторинга», «Главная страница» и «Чат». Теперь на консоли появилось сообщение «панель управления отключена».

Из документов react:
Если вы хотите запустить эффект и очистить его только один раз (при монтировании и размонтировании), вы можете передать пустой массив ([]) в качестве второго аргумента