Как передать параметры с помощью history.push / Link / Redirect в реакции-маршрутизаторе v4?

218

Как мы можем передать параметр this.props.history.push('/page')в React-Router v4?

.then(response => {
       var r = this;
        if (response.status >= 200 && response.status < 300) {
             r.props.history.push('/template');
          });
IshanGarg
источник
Компонент , который вынесенный Routeдолжен иметь доступ к this.props.location, this.props.historyи т.д. Я думаю , что вам не нужно использовать refбольше с v4. Попробуйте сделатьthis.props.history.push('/template');
saadq
Это не ссылка, это переменная, указывающая на это; this.props.history.push ( '/ шаблон'); перенесите меня на следующую страницу, но я хочу передать им реквизит .ref = this;
ИшанГарг
Вы пытаетесь перейти propsна компонент, который соответствует маршруту? Я думаю, что этот поток GitHub решает вашу проблему.
saadq
JFYI - Я удалил <a href> и добавил <Link>, в котором также есть опция отправки состояния, доступ к которой можно получить на следующей странице через this.props.location.state.
Манохар Редди Поредди
Не могли бы вы отметить один из ответов как «ответ». Я уверен, что люди, которые проводят время, печатая их, оценят это.
Джеймс Полус

Ответы:

392

Прежде всего, вам не нужно делать var r = this;это, поскольку это if statementотносится к контексту самого обратного вызова, который, поскольку вы используете функцию стрелки, относится к контексту компонента React.

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

Объекты истории обычно имеют следующие свойства и методы:

  • длина - (число) Количество записей в стеке истории
  • action - (строка) Текущее действие (PUSH, REPLACE или POP)
  • Местоположение - (объект) Текущее местоположение. Может иметь следующие свойства:

    • путь - (строка) путь URL
    • поиск - (строка) Строка запроса URL
    • hash - (строка) URL-фрагмент хеша
    • состояние - (строка) специфичное для местоположения состояние, которое было предоставлено, например, push (путь, состояние), когда это местоположение было помещено в стек. Доступно только в браузере и истории памяти.
  • push (путь, [состояние]) - (функция) Добавляет новую запись в стек истории
  • replace (путь, [состояние]) - (функция) Заменяет текущую запись в стеке истории
  • go (n) - (function) Перемещает указатель в стеке истории на n записей
  • goBack () - (function) Эквивалент go (-1)
  • goForward () - (function) Эквивалент go (1)
  • блок (подсказка) - (функция) Предотвращает навигацию

Таким образом, во время навигации вы можете передавать реквизиты для объекта истории, как

this.props.history.push({
  pathname: '/template',
  search: '?query=abc',
  state: { detail: response.data }
})

или аналогично для Linkкомпонента или Redirectкомпонента

<Link to={{
      pathname: '/template',
      search: '?query=abc',
      state: { detail: response.data }
    }}> My Link </Link>

а затем в компоненте, который отображается с /templateмаршрутом, вы можете получить доступ к пропущенным реквизитам, как

this.props.location.state.detail

Также имейте в виду, что при использовании объектов истории или местоположения из реквизита необходимо подключить компонент withRouter.

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

withRouter

Вы можете получить доступ к свойствам объекта истории и ближайшему <Route>'sсовпадению через withRouterкомпонент высшего порядка. withRouter будет повторять рендеринг своего компонента каждый раз, когда маршрут изменяется с теми же параметрами, что и <Route>рендер props: { match, location, history }.

Шубхам Хатри
источник
3
да, это сработало. Спасибо! Но не уверен, почему this.props.history.push('/template',response.data)не работает. Согласно документам push(path, [state]), вы не думаете, что это должно работать?
Санкет Патель
1
Спасибо за это! В моем случае я только передавал историю напрямую, поэтому я получил доступ к своей опоре через this.props.history.location.state.propName -
Nunchucks
@SanketPatel Вы должны сделать это this.props.history.push ('/ template', {response: response.data})
Арсалан Ахмед Кверши
Можно ли открыть маршрут в новой вкладке при передаче данных в переменную состояния, при навигации можно передавать реквизиты объекту истории?
Гаурав Кумар
3
как насчет goBack ()? при переходе назад с помощью goBack () я не вижу ни одного из состояний истории ни в props.location, ни в props.history.location. Навигация вперед с помощью push () работает нормально
MariusB
40

ты можешь использовать,

this.props.history.push("/template", { ...response }) или this.props.history.push("/template", { response: response })

тогда вы можете получить доступ к проанализированным данным из /templateкомпонента, следуя коду,

const state = this.props.location.state

Узнайте больше о React Session History Management

Тенуша Гуруге
источник
Эта логика работала для меня, когда history.push с back_url в состоянии this.props.history.push (redirect_url, {back_url: '/ needing_url'}); и получить это на целевой странице this.props.location.state.back_url
Брахам Дев Ядав
25
  • Для более ранних версий:

    history.push('/path', yourData);

    И получите данные в связанном компоненте, как показано ниже:

    this.props.location.state // it is equal to yourData
  • Для более новых версий вышеуказанный способ работает хорошо, но есть новый способ:

    history.push({
      pathname: '/path',
      customNameData: yourData,
    });

    И получите данные в связанном компоненте, как показано ниже:

    this.props.location.customNameData // it is equal to yourData

Подсказка : stateимя ключа использовалось в более ранних версиях, а для более новых версий вы можете использовать свое пользовательское имя для передачи данных, и использование stateимени не является обязательным.

AmerllicA
источник
Пожалуйста, поделитесь ссылкой, в которой говорится, что государство не является существенным, если оно у вас есть под рукой
Акшай Виджай Джайн
Уважаемый @AkshayVijayJain, это мой опыт кодирования. Я не написал это предложение на основе документа или ссылки.
AmerllicA
22

Расширение решения (предложенного Шубхам Хатри) для использования с крючками React (16.8 и далее):

package.json (always worth updating to latest packages)

{
     ...

     "react": "^16.12.0",
     "react-router-dom": "^5.1.2",

     ...
}

Передача параметров с историей push:

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

const FirstPage = props => {
    let history = useHistory();

    const someEventHandler = event => {
       history.push({
           pathname: '/secondpage',
           search: '?query=abc',
           state: { detail: 'some_value' }
       });
    };

};

export default FirstPage;

Доступ к переданному параметру с использованием useLocation из'act-router-dom ':

import { useEffect } from "react";
import { useLocation } from "react-router-dom";

const SecondPage = props => {
    const location = useLocation();

    useEffect(() => {
       console.log(location.pathname); // result: '/secondpage'
       console.log(location.search); // result: '?query=abc'
       console.log(location.state.detail); // result: 'some_value'
    }, [location]);

};
akhouri
источник
Большое спасибо, не смог найти обновленную альтернативу, кроме вашего ответа!
jamezrin
10

Если вам нужно передать параметры URL

Theres большое сообщение объяснение Тайлер Макгиннис на своем сайте, ссылка на пост

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

  1. на компоненте history.push:

    this.props.history.push(`/home:${this.state.userID}`)

  2. на компоненте роутера вы определяете маршрут:

    <Route path='/home:myKey' component={Home} />

  3. на домашнем компоненте:

componentDidMount(){
    const { myKey } = this.props.match.params
    console.log(myKey )
}
shyke
источник
У меня есть что-то вроде этого, но если я
обновляю
@rabiaasif, поскольку данных больше нет, вам нужно сохранить их или хранить в локальном хранилище
Дрю Кордано,
3

Не нужно использовать с рутером. Это работает для меня:

На вашей родительской странице

<BrowserRouter>
   <Switch>
        <Route path="/routeA" render={(props)=> (
          <ComponentA {...props} propDummy={50} />
        )} />

        <Route path="/routeB" render={(props)=> (
          <ComponentB {...props} propWhatever={100} />
          )} /> 
      </Switch>
</BrowserRouter>

Затем в ComponentA или ComponentB вы можете получить доступ

this.props.history

объект, включая метод this.props.history.push.

joedotnot
источник
Я думаю, что вам не нужно, withRouterпотому что вы обернули свой компонент BrowserRouter, который работает так же.
Пирог «О», тьфу
Да, и вы проходите propsвниз в каждый компонент, который включает в себя historyопору.
Джереми
2

Чтобы использовать React 16.8+ (с крючками), вы можете использовать этот способ

import React from 'react';
import { useHistory } from 'react-router-dom';

export default function SomeFunctionalComponent() {
let history = useHistory(); // should be called inside react component

const handleClickButton = () => {    
"funcionAPICALL"
       .then(response => {
             if (response.status >= 200 && response.status < 300) {
                 history.push('/template');
              });
}

return ( <div> Some component stuff 
    <p>To make API POST request and redirect to "/template" click a button API CALL</p>
    <button onClick={handleClickButton}>API CALL<button>
</div>)
} 

Источник здесь, чтобы прочитать больше https://reacttraining.com/react-router/web/example/auth-workflow

П Милл
источник
-12

Добавить информацию, чтобы получить параметры запроса.

const queryParams = new URLSearchParams(this.props.location.search);
console.log('assuming query param is id', queryParams.get('id');

Для получения дополнительной информации о URLSearchParams проверьте эту ссылку URLSearchParams

Камаль Пандей
источник
1
Это совсем не относится к React Router 4.
Колби Кокс