Обнаружение изменения маршрута с помощью ретранслятора

Мне нужно реализовать некоторую бизнес-логику в зависимости от истории просмотров.

Я хочу сделать что-то вроде этого:

reactRouter.onUrlChange(url => {
   this.history.push(url);
});

Есть ли способ получить обратный вызов от реагирующего маршрутизатора при обновлении URL?

Ответ 1

Вы можете использовать функцию history.listen() при попытке обнаружить изменение маршрута. Учитывая, что вы используете react-router v4, оберните свой компонент withRouter HOC, чтобы получить доступ к опоре history.

history.listen() возвращает функцию unlisten. Вы должны использовать это для unregister для прослушивания.

Вы можете настроить маршруты, например

index.js

ReactDOM.render(
      <BrowserRouter>
            <AppContainer>
                   <Route exact path="/" Component={...} />
                   <Route exact path="/Home" Component={...} />
           </AppContainer>
        </BrowserRouter>,
  document.getElementById('root')
);

а затем в AppContainer.js

class App extends Component {

  componentWillMount() {
    this.unlisten = this.props.history.listen((location, action) => {
      console.log("on route change");
    });
  }
  componentWillUnmount() {
      this.unlisten();
  }
  render() {
     return (
         <div>{this.props.children}</div>
      );
  }
}
export default withRouter(App);

Из истории docs:

Вы можете прослушивать изменения в текущем местоположении, используя history.listen:

history.listen((location, action) => {
      console.log(`The current URL is ${location.pathname}${location.search}${location.hash}`)
  console.log(`The last navigation action was ${action}`)
})

Объект location реализует подмножество window.location интерфейс, включая:

**location.pathname** - The path of the URL
**location.search** - The URL query string
**location.hash** - The URL hash fragment

У местоположений также могут быть следующие свойства:

location.state. Некоторое дополнительное состояние для этого местоположения, которое не находится в URL-адресе (поддерживается в createBrowserHistory и createMemoryHistory)

location.key - уникальная строка, представляющая это местоположение (поддерживается в createBrowserHistory и createMemoryHistory)

Действие является одним из PUSH, REPLACE, or POP в зависимости от того, как пользователь попал в текущий URL.

Когда вы используете реактивный маршрутизатор v3, вы можете использовать пакет history.listen() из history, как указано выше, или вы также можете использовать browserHistory.listen()

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

import {browserHistory} from 'react-router';

class App extends React.Component {

    componentDidMount() {
          this.unlisten = browserHistory.listen( location =>  {
                console.log('route changes');

           });

    }
    componentWillUnmount() {
        this.unlisten();

    }
    render() {
        return (
               <Route path="/" onChange={yourHandler} component={AppContainer}>
                   <IndexRoute component={StaticContainer}  />
                   <Route path="/a" component={ContainerA}  />
                   <Route path="/b" component={ContainerB}  />
            </Route>
        )
    }
} 

Ответ 2

Если вы хотите прослушивать объект history глобально, вам нужно создать его самостоятельно и передать его в Router. Затем вы можете прослушать его с помощью метода listen():

// Use Router from react-router, not BrowserRouter.
import { Router } from 'react-router';

// Create history object.
import createHistory from 'history/createBrowserHistory';
const history = createHistory();

// Listen to history changes.
// You can unlisten by calling the constant (`unlisten()`).
const unlisten = history.listen((location, action) => {
  console.log(action, location.pathname, location.state);
});

// Pass history to Router.
<Router history={history}>
   ...
</Router>

Еще лучше, если вы создаете объект истории как модуль, поэтому его можно легко импортировать в любом месте, где это может понадобиться (например, import history from './history';