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

Как мы можем передать параметр с 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');
          });

13 ответов

Прежде всего, вам не нужно делать 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 },

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

package.json (always worth updating to latest packages)

{
     ...

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

     ...
}

Передача параметров с толчком истории:

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 из response-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]);

};

  • Для более ранних версий:

    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 имя не имеет значения.

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

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

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

const state = this.props.location.state

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

Если вам нужно передать параметры 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 ) }

Реагируйте на TypeScript с помощью хуков

Из класса

  this.history.push({
      pathname: "/unauthorized",
      state: { message: "Hello" },
    });

Несанкционированный функциональный компонент

interface IState {
  message?: string;
}

export default function UnAuthorized() {
  const location = useLocation();
  const message = (location.state as IState).message;

  return (
    <div className="jumbotron">
      <h6>{message}</h6>
    </div>
  );
}

Проходить

      history.push({pathname:"/yourroute",state: {_id: "0001", name: "AZ"}})

Читать

      import React from 'react';

const YourRoute = props=> {
    const { _id, name } = (props.location && props.location.state) || {};
        //_id and name will contain the data passed data
     .
     .
     .

}

Вот рабочий пример

Я создал собственный перехватчик useQuery

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

const useQuery = (): URLSearchParams => {
  return new URLSearchParams(useLocation().search)
}

export default useQuery

Используйте это как

const query = useQuery();
const id = query.get("id") as string

Отправить как так

history.push({  
 pathname: "/template",
 search: `id=${values.id}`,
});
                  

Чтобы использовать функциональный компонент React 16.8 (withHooks), вы можете использовать этот способ.
Мы отправляем PhoneNumber на следующую страницу
Login.js.

          import { useHistory } from 'react-router-dom';
    const history = useHistory();
        const handleOtpVerify=(phoneNumber)=>
          {
               history.push("/OtpVerifiy",{mobNo:phoneNumber})
          } 

<button onClick={handleOtpVerify}> Submit </button>

OtpVerify.js

          import  useLocation  from 'react-router-dom';
    const [phoneNumber, setphoneNumber] = useState("")
        useEffect(() => {
                setphoneNumber(location.state.mobNo)
            }, [location]);
    return (
    <p>We have sent Verification Code to your</p>
    <h1>{phoneNumber}</h1>
    )

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

В вашем исходном компоненте

      this.props.history.push(pathComponent, sendState);

pathComponent целевой компонент, который получит состояние

В вашем целевом компоненте вы можете получить подобное состояние, если вы используете компонент класса

  • Версия Javascript
      constructor(props) {
  this.state = this.props.location.state
}
  • Версия машинописного текста
      constructor(props: {}) {
  const receiveState = this.props.location.state as StateType // you must parse into your state interface or type
  this.state = receiveState
}

Бонус

Если вы хотите сбросить полученное состояние. Использовать history чтобы заменить место, как это

      this.props.history({pathName: currentPath, state: resetState})

currentPathпуть к целевому компонентуresetState это новое значение, указывающее, что вы хотите

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

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

<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.

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

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

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

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

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

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