Обнаружение предыдущего пути в ответном маршрутизаторе?

Я использую реактивный маршрутизатор. Я хочу обнаружить предыдущую страницу (в том же приложении), откуда я пришел. У меня есть маршрутизатор в моем контексте. Но я не вижу никаких свойств, таких как "предыдущий путь" или история на объекте маршрутизатора. Как это сделать?

Ответ 1

Вы можете сохранить предыдущий путь в методе жизненного цикла componentWillReceiveProps. Логика очень близка к примеру, представленному в разделе раздел устранения неполадок react-router docs.

<Route component={App}>
  {/* ... other routes */}
</Route>

const App = React.createClass({
  getInitialState() {
    return { prevPath: '' }
  },

  componentWillReceiveProps(nextProps) {
    if (nextProps.location !== this.props.location) {
      this.setState({ prevPath: this.props.location })
    }
  }
})

И в последнее время доступ к нему из состояния.

Ответ 2

Вы можете передать состояние с помощью компонента <Link>, в данном случае это путь:

<Link to={{pathname: '/nextpath', state: { prevPath: location.pathname }}}>Example Link</Link>

Затем вы можете получить доступ к prevPath из this.props.location.state в следующем компоненте

Ответ 3

Если вы используете react-router-redux, вы можете создать редуктор, который перехватывает события, отправленные обработчиком реакции-маршрутизатора.

export default function routerLocations(state = [], action) {
  switch (action.type) {
    case "@@router/LOCATION_CHANGE":
      return [...state, action.payload]
    default:
      return state;
  }
}

Ответ 4

Если вы используете компонент <Redirect />, вы можете добавить свойство from, которое будет добавлено в location.state в компоненте, на который вы перенаправляете.

// in the redirecting component
<Redirect
to={{
  pathname: '/login',
  state: { from: location }
}}
/>

//in the other component you redirected to
...
const { location } = props.location.state;
...

Ответ 5

Для React Router 5 и Redux вы можете прослушать изменения местоположения и сохранить последний путь в магазине.

Определите действие и редуктор для ветки вашего штата, напр. misc:

// Partial state
const miscState = {
  prevPath: '',
  // ...other properties
}

// Action creator
export const updatePrevPathAction = path => ({
  type: 'misc/prev-path',
  payload: path,
})

// Partial reducer
export const miscReducer = (state = miscState, action) {
  switch (action.type) {
    case 'misc/prev-path':
      if (state.prevPath === action.payload) {
        state = { ...state, prevPath: action.payload }
      }
      break
    // ...handle other actions
  }
  return state
}

Затем, при создании магазина, если вы используете пользовательскую историю браузера:

// Import the history
import { browserHistory } from 'your-singleton-loc/browser-history'
import { updatePrevPathAction, miscReducer } from './misc-state'

// ...
// Create the store
const store = configureStore(...)

// Create a listener for browser history
const pathListener = loc => {
  store.dispatch(updatePrevPathAction(loc.pathname))
}
// Register the listener
browserHistory.listen(pathLisneter)
// Save the current uri
pathListener(browserHistory.location)

// done
return store

Если вы не используете пользовательскую историю браузера, вы можете сделать то же самое в файле App.jsx, используя свойство истории маршрутизатора.

Это решение для всего приложения, и для него не требуется response-router-redux.