@rexlabs-spicerhaart/whereabouts v1.1.0
Whereabouts - a (fairly) lightweight Redux location manager
Redux first abstraction of browser history management. Stores normalised current location and location history in Redux to be consumed by React components to render routes accordingly.
See concept for more details.
Usage
Installation
$ yarn add @rexlabs/whereabouts
Examples
Setting up the Redux store
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { whereaboutsReducer as whereabouts, whereaboutsMiddleware } from '@rexlabs/whereabouts';
const store = createStore(
combineReducers({ whereabouts: whereabouts }), // here we choose "whereabouts" as the state key
{},
applyMiddleware([ whereaboutsMiddleware ]) // needed to initialize history listener
);
export default store;
Connecting a component
To get the current location data from Redux, you can either @connect
manually, or use the HoC react-whereabouts
provides in order to de-normalize the state. It uses memoization under the hood, so there won't be unnecessary rerenders due to the state mapping.
import { withWhereabouts } from '@rexlabs/react-whereabouts';
@withWhereabouts
class Example extends Component {
render () {
const { whereabouts } = this.props;
return (
<div>
<h1>Current Location:</h1>
<ul>
<li>Path: {whereabouts.path}</li>
<li>Hash: {whereabouts.hash}</li>
<li>Query: {whereabouts.query}</li>
</ul>
<h1>History:</h1>
<pre>{JSON.stringify(whereabouts.history, null, 2)}</pre>
</div>
);
}
}
export default Example;
Using a different Redux store key to "whereabouts"
If you've setup your Redux store with whereabout's reducer under a key other than "whereabouts"
, then you will need to specify that key when using the withWhereabouts
HOC.
A suggestion would be to do this once in your App, and use that "namespaced" version of our withWhereabouts
everywhere else in your App.
// ./src/utils/with-router.js
import { withWhereabouts } from '@rexlabs/react-whereabouts';
const withRouter = withWhereabouts('router');
export default withRouter;
Dispatching actions
Whereabouts splits the concerns of source of truth for location data (Redux) and actions (History). Since the location manager should be able to receive actions from anywhere (you, the browser, 3rd party libs, etc), it needs to rely on history actions rather than Redux actions. The history actions then trigger Redux actions in the core.
import { push, replace, pop, go, goForwards, goBackwards } from '@rexlabs/whereabouts';
push({
path: '/example',
query: { foo: 'bar' }
})
// => /example?foo=bar
URL placeholders
You can define placeholders in your URL configs that will be passed down as param variables, e.g. entity ids, etc. Whereabouts uses path-to-regex
in the core to parse the URLs, so all its rules apply here as well, e.g.:
Normal placeholder
/path/:var
Regex
/path/:var([0-9]+)
Optional
/path/:var?
Wildcard
Wildcards are basically just unnamed regex placeholders.
/path/(.*)/something
Unnamed placeholders will not be passed down as params! Besides the path whereabouts also parses hash strings for possible url placeholders, so you can use the same syntax and patterns there as well.
More Reading
This is by no means a new concept. Other libraries already follow the same concept, so if you think whereabouts is not the perfect match for you, definitely have a look at other implementations:
Libraries used
Development
Install dependencies
$ yarn
Available Commands
$ yarn test # runs all units tests
$ yarn test:watch # runs unit tests when files change
$ yarn build # bundles the package for production
$ yarn start # runs storybook
See Routing Examples
$ yarn
$ yarn start
This will open up storybook with several example stories, that represent the routing requirements we had in past projects (Satchel, Flow, Rex) as well as an example story that just visualised the data flows.
Legal
Copyright © 2018 Rex Software All Rights Reserved.
3 years ago