{"id":21937625,"url":"https://github.com/cap32/react-router-mobx","last_synced_at":"2025-07-29T08:07:24.617Z","repository":{"id":57343801,"uuid":"101492835","full_name":"Cap32/react-router-mobx","owner":"Cap32","description":"📡 When React Router meets MobX: observable router and location","archived":false,"fork":false,"pushed_at":"2018-11-08T08:47:55.000Z","size":123,"stargazers_count":14,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-22T12:12:46.705Z","etag":null,"topics":["location","mobx","observable","query","querystring","react","react-router","router"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Cap32.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-26T14:59:42.000Z","updated_at":"2023-03-04T05:34:31.000Z","dependencies_parsed_at":"2022-09-12T06:51:01.070Z","dependency_job_id":null,"html_url":"https://github.com/Cap32/react-router-mobx","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Freact-router-mobx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Freact-router-mobx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Freact-router-mobx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cap32%2Freact-router-mobx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Cap32","download_url":"https://codeload.github.com/Cap32/react-router-mobx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250237832,"owners_count":21397401,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["location","mobx","observable","query","querystring","react","react-router","router"],"created_at":"2024-11-29T01:20:51.033Z","updated_at":"2025-04-22T12:12:51.621Z","avatar_url":"https://github.com/Cap32.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-router-mobx\n\n[![Build Status](https://travis-ci.org/Cap32/react-router-mobx.svg?branch=master)](https://travis-ci.org/Cap32/react-router-mobx)\n[![Coverage Status](https://coveralls.io/repos/github/Cap32/react-router-mobx/badge.svg?branch=master)](https://coveralls.io/github/Cap32/react-router-mobx?branch=master)\n[![npm version](https://badge.fury.io/js/react-router-mobx.svg)](https://badge.fury.io/js/react-router-mobx)\n[![License](https://img.shields.io/badge/license-MIT_License-blue.svg?style=flat)](https://github.com/Cap32/react-router-mobx/blob/master/LICENSE.md)\n\nWhen [React Router](https://reacttraining.com/react-router/) meets [MobX](https://mobx.js.org/): observable router and location.\n\n## Table of Contents\n\n\u003c!-- MarkdownTOC autolink=\"true\" bracket=\"round\" --\u003e\n\n- [Table of Contents](#table-of-contents)\n- [Features](#features)\n- [WTF](#wtf)\n- [Installation](#installation)\n- [Usage](#usage)\n- [API Reference](#api-reference)\n  - [RouterStore](#routerstore)\n  - [Router](#router)\n  - [setQueryString(queryString)](#setquerystringquerystring)\n- [match](#match)\n- [Versioning](#versioning)\n- [License](#license)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n## Features\n\n- `location` is observable\n- Built-in `query` observable object to `location`\n- Super easy to push/update new URL, pathname, hash, search or query\n\n## WTF\n\nIf you wanna push url from `http://aweso.me/search?q=hello\u0026page=4` to `http://aweso.me/search?q=hello\u0026page=5`, you may need:\n\n##### Before\n\n```js\nimport React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { withRouter } from \"react-router-dom\";\nimport { observer } from \"mobx-react\";\nimport qs from \"qs\";\nimport myStore from \"./stores/myStore\";\n\n@withRouter\n@observer\nexport default class MyApp extends Component {\n  static propTypes = {\n    location: PropTypes.object.isRequired,\n    history: PropTypes.object.isRequired\n  };\n\n  goToNextPage = ev =\u003e {\n    ev.preventDefault();\n    const { location, history } = this.props;\n    const query = qs.parse(location.search ? location.search.slice(1) : \"\");\n    history.push({\n      ...location,\n      search:\n        \"?\" +\n        qs.stringify({\n          ...query,\n          page: 1 + query.page\n        })\n    });\n  };\n\n  render() {\n    const { location } = this.props;\n    const { page } = qs.parse(location.search ? location.search.slice(1) : \"\");\n    return (\n      \u003cdiv\u003e\n        \u003cdiv\u003e{myStore.someContent}\u003c/div\u003e\n        \u003cp\u003ePage: {page || 1}\u003c/p\u003e\n        \u003cbutton onClick={this.goToNextPage}\u003eNext\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n##### After\n\n```js\nimport React, { Component } from \"react\";\nimport PropTypes from \"prop-types\";\nimport { observer } from \"mobx-react\";\nimport myStore from \"./stores/myStore\";\nimport routerStore from \"./stores/routerStore\";\n\n@observer\nexport default class MyApp extends Component {\n  goToNextPage = ev =\u003e {\n    ev.preventDefault();\n    const { location } = routerStore;\n    location.query = {\n      ...location.query,\n      page: 1 + location.query.page\n    };\n  };\n\n  render() {\n    const { page } = routerStore.location.query;\n    return (\n      \u003cdiv\u003e\n        \u003cdiv\u003e{myStore.someContent}\u003c/div\u003e\n        \u003cp\u003ePage: {page || 1}\u003c/p\u003e\n        \u003cbutton onClick={this.goToNextPage}\u003eNext\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n## Installation\n\n```bash\nyarn add react-router-mobx\n```\n\nYou should install all the peer dependencies if you haven't installed them:\n\n```bash\nyarn add react mobx mobx-react react-router-dom\n```\n\nIf you are using React Native, please install `react-router-native` instead of `react-router-dom`.\n\n## Usage\n\n1. Use react-router-mobx `Router` instead of react-router `Router`\n2. Pass a `RouterStore` instance and react-router `Router` component to `Router` component:\n\n```js\nimport React, { Component } from \"react\";\nimport { Router, RouterStore } from \"react-router-mobx\";\nimport { BrowserRouter, Route } from \"react-router-dom\";\n\nconst routerStore = new RouterStore();\n\nexport default class App extends Component {\n  render() {\n    return (\n      \u003cRouter component={BrowserRouter} routerStore={routerStore}\u003e\n        \u003cRoute {...someRouteConfigs} /\u003e\n      \u003c/Router\u003e\n    );\n  }\n}\n```\n\n## API Reference\n\n### RouterStore\n\nThe MobX store class that contains some router properties and methods.\n\n###### RouterStore#location\n\nA little bits like react-router `location` object which contains `key`, `pathname`, `search`, `hash`, `state`. But there are several differences:\n\n- Prividing `query` object, just like react-router v3 or below\n- All properties are observable and mutable\n- Could push URL by passing new location or properties, just like `window.location`\n  - Push a new URL: `routerStore.location = '/foo?say=hello'`\n  - Push a new `pathname`, i.e. from `/foo?say=hello` to `/bar?say=hello`: `routerStore.location.pathname = '/bar'`\n  - Push a new `search`, i.e. from `/foo?say=hello` to `/foo?say=world`: `routerStore.location.query = { say: 'world' }` or `routerStore.location.search = '?say=world'`\n\n###### RouterStore#history\n\nJust like react-router `history` object, except for `history.listen`:\n\n```js\nhistory.listen((location, prevLocation, action) =\u003e {\n  console.log(\n    `The current URL is ${location.pathname}${location.search}${location.hash}`\n  );\n  console.log(\n    `The previous URL is ${prevLocation.pathname}${prevLocation.search}${\n      prevLocation.hash\n    }`\n  );\n});\n```\n\n###### RouterStore#push(loc, state)\n\nLike react-router `history.push(loc, state)`, but the `loc` param supports to be an object that contains a `query` object.\n\n###### RouterStore#replace(loc, state)\n\nLike react-router `history.replace(loc, state)`, but the `loc` param supports to be an object that contains a `query` object.\n\n### Router\n\nThe low-level api router component instead of react-router `Router` component.\n\n###### Props\n\n- routerStore (RouterStore): Defining a `RouterStore` instance to store or update `location` state\n- component (ReactComponent): Defining the react router component, e.g. `BrowserRouter`, `MemoryRouter`, `NativeRouter`, etc. Defaults to react-router `Router` component\n- history (Object): You can also define a custom history object, just like react-router `Router` component\n- All properties in react-router `Router` are supported\n\n### setQueryString(queryString)\n\nSetting a custom `queryString` library.\n\n###### Arguments\n\n1. queryString (Object): Custom `queryString` library, which should contain `parse(object)` and `stringify(object)` methods\n\n###### Example\n\n```js\nimport { setQueryString } from \"react-router-mobx\";\nimport { parse, stringify } from \"qs\";\nsetQueryString({ parse, stringify });\n```\n\n## match\n\nPlease note that routerStore doesn't provide a `match` prop, if you need `match`, you may also use `withRouter` or `\u003cRoute\u003e` from `react-router`. Checkout [match](https://reacttraining.com/react-router/web/api/match) for detail.\n\n## Versioning\n\nThis library follows [Semantic Versioning](http://semver.org/).\n\nThis library is considered to be **General Availability (GA)**. This means it\nis stable; the code surface will not change in backwards-incompatible ways\nunless absolutely necessary (e.g. because of critical security issues) or with\nan extensive deprecation period. Issues and requests against **GA** libraries\nare addressed with the highest priority.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcap32%2Freact-router-mobx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcap32%2Freact-router-mobx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcap32%2Freact-router-mobx/lists"}