Как перенаправить старый реагирующий маршрутизатор HashRouter (с #) на BrowserRouter?

Мы заменяем react-router-doms HashRouter на BrowserRouter и хотели бы перенаправить старые маршруты на новые. Я отметил nginx, потому что я не против сделать там редиректы. :)

Допустим, у нас есть старый маршрут /#/users и /#/users:id: они должны совпадать и перенаправлять на /users и /users/:id.

Пока я пробовал (react-router-dom v5.0.1):

<Router>
  <Switch>
    <Route path='/users' component = {UsersComponent} />
    <Route path='/users/:id' component = {UsersDashComponent} />
  </Switch>
  <Redirect from='/#/users' to '/users' />
  <Redirect from='/#/users/:id' to='/users/:id' />
</Router>

Первый маршрут совпадает и перенаправляется нормально. Второй (с id) проблематичен. Когда я перехожу к /#/users/123, он перенаправляется на /users/:id. Это замена фактического 123 на :id.

Это два примера маршрутов. У нас есть еще с параметрами для перенаправления.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
0
9 385
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Я думаю, для навигации вы используете что-то вроде этого,

<Link to = "/#/users" />
<Link to = "/#/users/123" />

Согласно документы,

A <Router> that uses the hash portion of the URL (i.e. window.location.hash) to keep your UI in sync with the URL.

При использовании HashRouter вам не нужно добавлять # вручную, маршрутизатор React автоматически добавляет # в URL

Так что ваши маршруты должны быть,

import { HashRouter } from 'react-router-dom'


<HashRouter>
  <Switch>
    <Route exact path='/users' component = {UsersComponent} />
    <Route exact path='/users/:id' component = {UsersDashComponent} />
  </Switch>
</HashRouter>

И ссылки должны быть,

<Link to = "/users" />
<Link to = "/users/123" />

Теперь перейдем к вашему вопросу, как заменить HashRouter на BrowserRouter?

Для этого вам просто нужно сделать это,

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


<BrowserRouter>
  <Switch>
    <Redirect from='/#/users' to '/users' />
    <Redirect from='/#users/:id' to='/users/:id' />
    <Route exact path='/users' component = {UsersComponent} />
    <Route exact path='/users/:id' component = {UsersDashComponent} />
  </Switch>
</BrowserRouter>

И ваши ссылки должны быть одинаковыми.

Примечание: Также посмотрите, я добавил exact к route, это будет точно соответствовать path.

Спасибо за подробное объяснение. Однако на самом деле я вообще не использую <Link>. Пользователи могут получить доступ к старым ссылкам с хэшем в своих закладках, электронной почте, на других сайтах и ​​т. д.

AlvMF1 12.07.2019 07:26

Итак, это не проблема реакции, а самого ngnix.

ravibagul91 12.07.2019 07:29

@ AlvMF1 Я обновил свой ответ. Убедитесь, что вы сначала написали <Redirect>, а затем на самом деле <Route>.

ravibagul91 12.07.2019 12:22

Неудачно. Ты пробовал? Меня перенаправляют только в том случае, если <Redirect> находится за пределами <Switch>, но, как говорится в вопросе, параметр - нет. Я получаю :id в качестве параметра...

AlvMF1 14.07.2019 02:02

Я не пробовал это, но в документах говорится только об этом - github.com/ReactTraining/react-router/blob/master/packages/…

ravibagul91 14.07.2019 02:27
Ответ принят как подходящий

Вот мое решение:

<Router>
  <Switch>
    <Route path='/users' component = {UsersComponent} />
    <Route path='/users/:id' component = {UsersDashComponent} />
    <Route exact path='/' render = {({ location }) => <Redirect to = {location.hash.replace('#', '')} />} />
  </Switch>
</Router>

Только маршруты, имеющие /#, будут соответствовать /. Можно легко добавить условие, если необходимо отобразить что-то в корне.

Честно говоря, ни одно из этих решений мне не помогло, я хотел выполнить перенаправление со всех моих предыдущих маршрутов на новые без #.

Хотя принятый ответ должен подойти для большинства случаев, я также обрабатываю 404, которые на самом деле не будут обнаружены таким перенаправлением.

Закончилось добавлением охранника, взаимодействующего с историей React Router перед рендерингом моего переключателя:

function App() {
  const history = useHistory()

  if (location.hash.startsWith('#/')) {
    history.push(location.hash.replace('#', '')) // or history.replace
  }

  return (
    <Switch>
      <Route path = "/" exact component = { Home } />
      ...
      <Route path = "*" component = { PageNotFound } />
    </Switch>
  )
}
export const history = createBrowserHistory();

export const App: FC = () => {
   return (
     <Router history = {history}>
       <Switch>
        <Route path = "/settings" exact component = {Settings} />
       </Switch>
     </Router>
  );
};


export const Settings : FC = () => {
   return (
      <HashRouter basename = "/" hashType = "noslash">
        <Switch>
              <Route path = "/profile">
                <Profile />
              </Route>
       </Switch>
    </HashRouter>
  );
};

 import {history} from "./App.tsx";

 export const Profile : FC = () => {
      return (
        <Router history = {history}>
           <Link to = "/product/1"/>
        </Router>
       );
    };

  // It's simple store your history in a variable and make use of it

Вопрос о том, как перенаправить пользователей со старых хеш-ссылок на новые (без хеша)

Max 08.08.2021 12:43

вы можете прочитать вопрос еще раз, там написано, как перенаправить с хэша на браузер !!!

Praveen Nagaraj 09.08.2021 14:29

правильно. но ваше решение не перенаправляет пользователя с URL-адреса, например: «/#/product/1» на «/product/1». Также автор говорит: > Пользователи могут получить доступ к старым ссылкам с хешем в своих закладках, электронной почте, на других сайтах и ​​т. д.

Max 09.08.2021 16:28

хорошо, @Max понял, что им нужно что-то вроде функциональности location.replace.

Praveen Nagaraj 10.08.2021 09:34

Другие вопросы по теме