0

"Не используйте Route или withRouter() вне Router при работе с react-router 4 и styled-components в React"

10

Я пытаюсь создать свой первый портфолио-сайт, но застрял с маршрутизацией, используя react-router-dom версии 4.2.2 и styled-components версии 2.2.3.

Я получаю сообщение об ошибке: "You should not use Route or withRouter() outside a Router".

Я также пробовал использовать Link вместо NavLink, но тоже получил ошибку: "You should not use Link outside a Router".

Кто-нибудь, помогите, пожалуйста.

navigationBar.js

import React, { Component } from 'react';
import { NavigationContainer, NavItem } from './navigationBar.style';

class NavigationBar extends Component {
  render() {
    return (
      <NavigationContainer>
        <NavItem to="/">Home</NavItem>
        <NavItem to="/projects">Project</NavItem>
      </NavigationContainer>
    );
  }
}

export default NavigationBar;

navigationBar.style.js

import styled from 'styled-components';
import { Flex, Div } from 'theme/grid';
import { NavLink } from 'react-router-dom';

export const NavigationContainer = styled(Flex)`
  position: fixed;
  right: 20px;
  top: 0.5em;
  font-size: 1em;  
`;
export const NavItem = styled(NavLink)`
  position: relative;
  padding-left: 10px;
  cursor: pointer;
`;

Как мне исправить эту проблему с маршрутизацией?

5 ответ(ов)

0

Убедитесь, что основной код рендеринга React обернут в Router. Например, если вы используете react-dom, вам нужно обернуть ваше приложение в BrowserRouter. Если это проект Udacity, обычно это файл index.js.

Вот пример кода:

import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
   <BrowserRouter>
     <App />
   </BrowserRouter>,
   document.getElementById('root')
);

Таким образом, ваше приложение сможет использовать маршрутизацию.

0

Вы используете NavLink вне BrowserRouter или HashRouter (в зависимости от того, что вы используете).

Вы сами об этом сказали:

Вы не должны использовать Link вне Router.

Убедитесь, что ваша структура выглядит примерно так:

// Отрисовка App или что-то другое
render() {
  return (
    <BrowserRouter>
       <NavigationBar />
       {`и все, что вы там делаете`}
    </BrowserRouter>
  );
}

Вы всегда должны рендерить их внутри Router.

0

Проблема, о которой вы говорите, действительно часто возникает из-за того, что в проекте использовано несколько копий React, что может привести к предупреждениям "Invalid hook call". Это связано с тем, что React может не правильно идентифицировать состояние компонентов, если они используют разные инстансы библиотеки.

Как вы упомянули в своем вопросе, причина вроде бы в использовании npm link, когда ваше приложение пытается использовать React из разных проектов, например "react-app" и "react-app-components". Это может привести к конфликтам, особенно при публикации в npm repository, когда ошибка исчезает, так как используется только одна версия React.

Что касается вашего решения: удаление зависимостей react и react-router-dom из файла package.json и повторная установка зависимостей — это хороший способ избежать дублирования этих библиотек. Когда вы оставляете только зависимости, связанные с типами @types/*, это позволяет использовать TypeScript без необходимости включать сами библиотеки в зависимости вашего проекта.

Ваш файл package.json до и после изменений показывает правильный подход:

Перед:

{
  //...
  "devDependencies": {
    //...
    "react": "^16.13.1",
    "react-router-dom": "^5.2.0",
    //...
  },
  "peerDependencies": {
    "react": "^16.13.1",
    "react-router-dom": "^5.2.0"
  }
}

После:

{
  //...
  "devDependencies": {
    //...
    // Здесь удалены "react" и "react-router-dom"
  },
  "peerDependencies": {
    "react": "^16.13.1",
    "react-router-dom": "^5.2.0"
  }
}

Таким образом, вы оставляете только peerDependencies, что обусловлено тем, что другие пакеты (например, react-app-components) теперь будут отвечать за установку React. Это помогает избежать проблемы с дублированием и улучшает совместимость компонентов.

Если у вас остались вопросы или вы столкнулись с другими проблемами, не стесняйтесь задавать их!

0

Это может быть результатом путаницы в node_modules для мультирепозиторных проектов с различными подходами интеграции.

Самый простой способ избежать подобных проблем — это иметь только одну папку node_modules для всех проектов, интегрированных в одно приложение. В противном случае некоторые подпроекты могут использовать разные версии одной и той же библиотеки (например, React или Router и т. д.), которые могут быть несовместимы друг с другом на уровне внутренних структур данных (реактивные контексты и так далее), что приводит к таким проблемам.

0

Проблема решается при использовании <Router>, просто разместите его снаружи </Router></AppProvider>. Вот пример кода:

<BrowserRouter>
    <Switch>
        {/* Пример маршрута */}
        <Route path="/index" render={(props) => <Index {...props} />} />
    </Switch>
</BrowserRouter>

Убедитесь, что вы правильно организовали структуру компонентов, чтобы избежать потенциальных проблем с контекстом, который предоставляет ваш AppProvider.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь