When React Router meets MobX: observable router and location.
- locationis observable
- Built-in queryobservable object tolocation
- Super easy to push/update new URL, pathname, hash, search or query
If you wanna push url from http://aweso.me/search?q=hello&page=4 to http://aweso.me/search?q=hello&page=5, you may need:
import React, { Component } from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router-dom";
import { observer } from "mobx-react";
import qs from "qs";
import myStore from "./stores/myStore";
@withRouter
@observer
export default class MyApp extends Component {
  static propTypes = {
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  };
  goToNextPage = ev => {
    ev.preventDefault();
    const { location, history } = this.props;
    const query = qs.parse(location.search ? location.search.slice(1) : "");
    history.push({
      ...location,
      search:
        "?" +
        qs.stringify({
          ...query,
          page: 1 + query.page
        })
    });
  };
  render() {
    const { location } = this.props;
    const { page } = qs.parse(location.search ? location.search.slice(1) : "");
    return (
      <div>
        <div>{myStore.someContent}</div>
        <p>Page: {page || 1}</p>
        <button onClick={this.goToNextPage}>Next</button>
      </div>
    );
  }
}import React, { Component } from "react";
import PropTypes from "prop-types";
import { observer } from "mobx-react";
import myStore from "./stores/myStore";
import routerStore from "./stores/routerStore";
@observer
export default class MyApp extends Component {
  goToNextPage = ev => {
    ev.preventDefault();
    const { location } = routerStore;
    location.query = {
      ...location.query,
      page: 1 + location.query.page
    };
  };
  render() {
    const { page } = routerStore.location.query;
    return (
      <div>
        <div>{myStore.someContent}</div>
        <p>Page: {page || 1}</p>
        <button onClick={this.goToNextPage}>Next</button>
      </div>
    );
  }
}yarn add react-router-mobxYou should install all the peer dependencies if you haven't installed them:
yarn add react mobx mobx-react react-router-domIf you are using React Native, please install react-router-native instead of react-router-dom.
- Use react-router-mobx Routerinstead of react-routerRouter
- Pass a RouterStoreinstance and react-routerRoutercomponent toRoutercomponent:
import React, { Component } from "react";
import { Router, RouterStore } from "react-router-mobx";
import { BrowserRouter, Route } from "react-router-dom";
const routerStore = new RouterStore();
export default class App extends Component {
  render() {
    return (
      <Router component={BrowserRouter} routerStore={routerStore}>
        <Route {...someRouteConfigs} />
      </Router>
    );
  }
}The MobX store class that contains some router properties and methods.
A little bits like react-router location object which contains key, pathname, search, hash, state. But there are several differences:
- Prividing queryobject, just like react-router v3 or below
- All properties are observable and mutable
- Could push URL by passing new location or properties, just like window.location- Push a new URL: routerStore.location = '/foo?say=hello'
- Push a new pathname, i.e. from/foo?say=helloto/bar?say=hello:routerStore.location.pathname = '/bar'
- Push a new search, i.e. from/foo?say=helloto/foo?say=world:routerStore.location.query = { say: 'world' }orrouterStore.location.search = '?say=world'
 
- Push a new URL: 
Just like react-router history object, except for history.listen:
history.listen((location, prevLocation, action) => {
  console.log(
    `The current URL is ${location.pathname}${location.search}${location.hash}`
  );
  console.log(
    `The previous URL is ${prevLocation.pathname}${prevLocation.search}${
      prevLocation.hash
    }`
  );
});Like react-router history.push(loc, state), but the loc param supports to be an object that contains a query object.
Like react-router history.replace(loc, state), but the loc param supports to be an object that contains a query object.
The low-level api router component instead of react-router Router component.
- routerStore (RouterStore): Defining a RouterStoreinstance to store or updatelocationstate
- component (ReactComponent): Defining the react router component, e.g. BrowserRouter,MemoryRouter,NativeRouter, etc. Defaults to react-routerRoutercomponent
- history (Object): You can also define a custom history object, just like react-router Routercomponent
- All properties in react-router Routerare supported
Setting a custom queryString library.
- queryString (Object): Custom queryStringlibrary, which should containparse(object)andstringify(object)methods
import { setQueryString } from "react-router-mobx";
import { parse, stringify } from "qs";
setQueryString({ parse, stringify });Please note that routerStore doesn't provide a match prop, if you need match, you may also use withRouter or <Route> from react-router. Checkout match for detail.
This library follows Semantic Versioning.
This library is considered to be General Availability (GA). This means it is stable; the code surface will not change in backwards-incompatible ways unless absolutely necessary (e.g. because of critical security issues) or with an extensive deprecation period. Issues and requests against GA libraries are addressed with the highest priority.
MIT