Как лучше всего перенаправить страницу с помощью React Router?

107

Я новичок в React Router и узнал, что существует так много способов перенаправить страницу:

  1. С помощью browserHistory.push("/path")

    import { browserHistory } from 'react-router';
    //do something...
    browserHistory.push("/path");
    
  2. С помощью this.context.router.push("/path")

    class Foo extends React.Component {
        constructor(props, context) {
            super(props, context);
            //do something...
        }
        redirect() {
            this.context.router.push("/path")
        }
    }
    
    Foo.contextTypes = {
        router: React.PropTypes.object
    }
    
  3. В React Router v4 есть this.context.history.push("/path")и this.props.history.push("/path"). Подробности: как отправить в историю в React Router v4?

Меня так сбивают с толку все эти варианты, есть ли лучший способ перенаправить страницу?

Лютон Чен
источник
вы используете v4 да?
azium
1
ссылка на другой стек, который вы опубликовали, довольно ясна, я бы рекомендовал использоватьwithRouter
azium

Ответы:

186

На самом деле это зависит от вашего варианта использования.

1) Вы хотите защитить свой маршрут от неавторизованных пользователей.

В этом случае вы можете использовать вызванный компонент <Redirect />и реализовать следующую логику:

import React from 'react'
import  { Redirect } from 'react-router-dom'

const ProtectedComponent = () => {
  if (authFails)
    return <Redirect to='/login'  />
  }
  return <div> My Protected Component </div>
}

Имейте в виду, что если вы хотите <Redirect />работать так, как вы ожидаете, вы должны поместить его в метод рендеринга вашего компонента, чтобы он в конечном итоге считался элементом DOM, иначе он не будет работать.

2) Вы хотите перенаправить после определенного действия (скажем, после создания элемента)

В этом случае вы можете использовать историю:

myFunction() {
  addSomeStuff(data).then(() => {
      this.props.history.push('/path')
    }).catch((error) => {
      console.log(error)
    })

или

myFunction() {
  addSomeStuff()
  this.props.history.push('/path')
}

Чтобы иметь доступ к истории, вы можете обернуть свой компонент HOC с именем withRouter. Когда вы оборачиваете им свой компонент, он проходит match locationи historyподпирает. Для получения более подробной информации ознакомьтесь с официальной документацией по withRouter .

Если компонент является дочерним по отношению к <Route />компоненту, то есть , если это что - то вроде <Route path='/path' component={myComponent} />, вы не должны обернуть компонент с withRouter, потому что <Route />перевалы match, locationи historyк своему ребенку.

3) Перенаправить после нажатия на какой-либо элемент

Здесь есть два варианта. Вы можете использовать history.push(), передав его onClickсобытию:

<div onClick={this.props.history.push('/path')}> some stuff </div>

или вы можете использовать <Link />компонент:

 <Link to='/path' > some stuff </Link>

Я думаю, что практическое правило в этом случае - <Link />сначала попробовать использовать , я полагаю, особенно из-за производительности.

Чагри Ярдимчи
источник
У меня работает `this.props.history.push (" / ");` React-router - v4.2 Спасибо @Cagri
MD
stackoverflow.com/questions/60579292/… Не могли бы вы взглянуть на этот вопрос?
a125,
В последнем варианте, поскольку компонент имеет historyв своих свойствах возможность делать this.props.history.push('/path'), это означает, что компонент является дочерним <Route/>или у него есть withRouterоболочка в экспорте правильно?
Андре
Таким образом, можно перейти к другому компоненту без указания <Route path='/path' component={Comp}/>, я думаю, просто render() { return <Comp/>}в условии?
Андре
@Andre да, это правильно для использования, this.props.historyно я не уверен, правильно ли я понял ваш второй вопрос? Что вы конкретно имеете в виду route to another component?
Чагри Ярдимчи
8

Теперь, с помощью react-router v15.1и далее, мы можем useHistoryподключиться. Это очень простой и понятный способ. Вот простой пример из исходного блога.

import { useHistory } from "react-router-dom";

function BackButton({ children }) {
  let history = useHistory()
  return (
    <button type="button" onClick={() => history.goBack()}>
      {children}
    </button>
  )
}

Вы можете использовать это в любом функциональном компоненте и пользовательских хуках. И да, это не будет работать с компонентами класса так же, как с любым другим хуком.

Узнайте больше об этом здесь https://reacttraining.com/blog/react-router-v5-1/#usehistory

Ананд Сингх
источник
3

Вы также можете использовать dom-библиотеку реактивного маршрутизатора useHistory;

`
import { useHistory } from "react-router-dom";

function HomeButton() {
  let history = useHistory();

  function handleClick() {
    history.push("/home");
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  );
}
`

https://reactrouter.com/web/api/Hooks/usehistory

Майя Либерман
источник
1

Один из самых простых способов: использовать ссылку следующим образом:

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

<Link to={`your-path`} activeClassName="current">{your-link-name}</Link>

Если мы хотим охватить весь раздел div ссылкой:

 <div>
     <Card as={Link} to={'path-name'}>
         .... 
           card content here
         ....
     </Card>
 </div>

РамешД
источник
0

Вы также можете в Redirectпределах Routeследующим образом . Это для обработки недопустимых маршрутов.

<Route path='*' render={() => 
     (
       <Redirect to="/error"/>
     )
}/>
Прамудитха
источник