Что-то делать, затем перенаправить в реакцию

MrJalapeno спросил: 28 марта 2018 в 03:37 в: reactjs

Краткая версия: когда пользователь нажимает кнопку, я хочу что-то сделать, а затем перенаправить пользователя. Как это сделать?


Более длинная версия:

У меня есть вложенные маршруты (не знаю, влияет ли это на проблему), как это настраивается описывается в довольно минимальном (насколько мне известно) примере здесь: ссылка на вопрос SO

Я хочу кнопку, которая сначала что-то делает, затем перенаправляет пользователя, поэтому я не могу использовать Link. Сначала я увидел

use this.props.history.push('/route') для этого

Но потом я узнал, что this.props.history isn ' t вещь, и теперь это собственный пакет npm. Здесь Я получил простое объяснение того, как реализовать то, что мне нужно.


Пример моей проблемы:

App.js сделать это:

<Router history={history}>
  <div>          
    <Link to="/">
      <button>Go to home</button>
    </Link>
  <Switch>
    <Route exact path="/other" component={() => <Other/>} />
    <Route path="/" component={() => <Home/>} />
  </Switch>
  </div>
</Router>

С двумя путями верхнего уровня, точный путь для /other, который отображает Other и выглядит например:

и относительный путь для /, который отображает Home и выглядит следующим образом:

Home отображает этот код:

<div>
  THIS IS HOME WOO!
  <div>
      <Route exact path="/" component={() => <HomeController/>} />
      <Route exact path="/about" component={() => <About/>} />
      <Route exact path="/click-page" component={() => <ClickPage/>} />              
  </div>
</div>

Теперь здесь по умолчанию используется HomeController (содержащий две кнопки со ссылками на страницу и клик), но /about renders и выглядит следующим образом:

и About отображает /click-page и выглядит следующим образом:


Здесь начинается ошибка: (

Итак ClickPage делает это:

<button onClick={clickHandler}>
  DO SOMETHING THEN GO TO ABOUT
</button>

, где ClickPage выглядит следующим образом:

function clickHandler(){
  console.log("doing stuff");
  history.push('/about');
}

clickHandler в этом случае импортируется из другого файла что выглядит следующим образом:

// history.js
import { createBrowserHistory } from 'history'export default createBrowserHistory({
/* pass a configuration object here if needed */
})

, который является символом по символу, скопированному из ответа , упомянутого ранее.

Проблема в том, что когда я нажимаю кнопку, это то, что я вижу:

Таким образом, функция он делает что-то, а затем толкает "/ about" к истории, но ничего не происходит. Почему это? Нужно ли принудительно преобразовывать history?

Полный пример кода, который я использовал для воссоздания проблемы, приведен ниже: pastebin-link

3 ответа

Gautam Naik ответил: 28 марта 2018 в 03:56

Во-первых,

this.props.history.push('/route')

все еще присутствует вact-router4. реквизит истории доступен только для прямого дочернего элемента маршрутизатора.

Если ваш компонент не является прямым дочерним элементом маршрутизатора, вы можете экспортировать этот компонент с помощью withRouter HOC, который можно импортировать следующим образом

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

, затем, по нажатию кнопки, вы можете делать вещи и использовать

this.props.history.push('/route')

для перехода в любое место

Colin ответил: 28 марта 2018 в 04:00

Вы можете использовать this.history.push в любом компоненте, отображаемом с помощью Route.

Пример кода здесь: https://codesandbox.io/s/w21m5mlvyw

MrJalapeno ответил: 28 марта 2018 в 04:36
Здорово! Работая над его реализацией, я думаю, что мог бы также узнать причину использовать component={ClickPage} вместо component={() => <ClickPage/>. Если я просто удаляю history={history} from Router` и меняю его на this.props.history.push, я получаю сообщение об ошибке, что у props нет history. Но если я изменю это, чтобы быть точно вашим кодом, это работает. Собираюсь присмотреться, что еще нужно.
Colin ответил: 28 марта 2018 в 05:30
Да, я рекомендую использовать шаблон component={Component}. Если это поможет, не стесняйтесь пометить как правильный :)
Hokagoka ответил: 28 марта 2018 в 04:01

Вы можете сделать это следующим образом.

import { Redirect } from 'react-router'
...render() {
...{fireRedirect && (
  <Redirect to={from || '/thank-you'}/>
)}

Обновить свое состояние fireRediect после того, как ваше действие пользователя будет выполнено

Это выглядит как то, что вам нужно здесь.