Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/miles-till/mobx-state-tree-router
State-based router for React and MobX State Tree
https://github.com/miles-till/mobx-state-tree-router
mobx mobx-state-tree react router
Last synced: about 1 month ago
JSON representation
State-based router for React and MobX State Tree
- Host: GitHub
- URL: https://github.com/miles-till/mobx-state-tree-router
- Owner: miles-till
- License: mit
- Created: 2019-04-01T04:38:13.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T01:46:28.000Z (almost 2 years ago)
- Last Synced: 2024-11-07T08:46:46.064Z (about 2 months ago)
- Topics: mobx, mobx-state-tree, react, router
- Language: JavaScript
- Size: 252 KB
- Stars: 18
- Watchers: 1
- Forks: 3
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# MobX State Tree Router
_State-based router for React and MobX State Tree_
[![npm](https://img.shields.io/npm/v/mobx-state-tree-router.svg)](https://www.npmjs.com/package/mobx-state-tree-router)
- [Inspiration](#inspiration)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Features](#features)
- [React components](#react-components)
- [MobX State Tree models](#mobx-state-tree-models)
- [Browser url matching and history binding](#browser-url-matching-and-history-binding)
- [Centralized view definitions](#centralized-view-definitions)
- [Route cycle hooks](#route-cycle-hooks)
- [Known Issues](#known-issues)## Inspiration
* [How to decouple state and UI (a.k.a. you don’t need componentWillMount)](https://hackernoon.com/how-to-decouple-state-and-ui-a-k-a-you-dont-need-componentwillmount-cc90b787aa37)
* [MobX Router](https://github.com/kitze/mobx-router)## Installation
Peer dependencies: `react react-dom mobx mobx-react mobx-state-tree`
NPM: `npm install --save mobx-state-tree-router`
Yarn: `yarn add mobx-state-tree-router`
## Quick Start
__index.js__
```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { RouterStore, View, startRouter, StateRouter, Link } from 'mobx-state-tree-router';const views = {
home: View.create({
name: 'home',
path: '/',
component:Home page
}),
about: View.create({
name: 'about',
path: '/about',
component:About page
})
};const router = RouterStore.create({
views: views
});startRouter(router);
ReactDOM.render((
Home
About
), document.getElementById('root'));
```## Features
### React components
* ``
* renders the appropriate component for the `router`'s `currentView`
* `currentView` can be set by calling `router.setView(view, params)` directly, or using a `Link` component
* props can be set for the rendered component by calling `router.setProps(props)`
* a component can be passed into the `loading` prop to display a loading indicator (e.g. ajax spinner)
* ``
* renders an `` element with `href` set to the result of `view.formatUrl(params)`### MobX State Tree models
* `RouterStore`
* exposes the available `routes` based on the `views`
* manages the `currentUrl` based on the `currentView` and `params`
* `setView(view, params)` can be called to change the route
* `setProps(props)` can be called to pass props to the `currentView`'s rendered component
* `View`
* defines a `name`, `route`, `component` to render
* defines optional change route `hooks`:
* `beforeExit(self, params)`
* `beforeEnter(self, params)`
* `onExit(self, params)`
* `onEnter(self, params)`
* `formatUrl(params)` can be called to get the url for this `view` given the `params` passed### Browser url matching and history binding
`startRouter(router)` binds the router to the browser's history object to update the url or parse a url change and set the appropriate view.
### Centralized view definitions
Views and their route cycle hooks (data fetching and business logic) can be defined in one centralized location:
__views.js__
```javascript
import { View } from 'mobx-state-tree-router';
import Home from 'components/Home';
import ItemList from 'components/ItemList';
import Item from 'components/Item';
export const views = {
home: View.create({
name: 'home',
path: '/',
component:
}),
items: View.create({
name: 'items',
path: '/items',
component:
hooks: {
async beforeEnter(self) {
await self.root.itemStore.loadItems();
}
}
}),
item: View.create({
name: 'item',
path: '/item/:itemId',
component:
hooks: {
async beforeEnter(self, params) {
self.router.setProps({ itemId: params.itemId });
await self.root.itemStore.loadItem(params.itemId);
}
}
})
};
```### Route cycle hooks
These hooks provide a way to run some code during a route change. They can be synchronous or asynchronous. The route change process is as follows:
* `router.setView` called
* `router.isLoading` set to `true`
* old view `beforeExit(self, params)`
* returning `false` will cancel the route change
* new view `beforeEnter(self, params)`
* returning `false` will cancel the route change
* route is updated and rendered
* `router.isLoading` set to `false`
* old view `onExit(self, params)`
* new view `onEnter(self, params)`## Known Issues
* `formatUrl` doesn't properly handle paths with catch-all `*`
* current workaround is to use `setView` in the `beforeEnter` hook of the catch-all to redirect to another view
* query parameters are not handled