Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement beginning of simpleRouter with support for hashes
- Loading branch information
Showing
8 changed files
with
100 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
This file contains information about the laboratory itself and design choices inside. | ||
|
||
## Simple Router | ||
The laboratory uses a simple routing system with no outside dependencies. The simple router is stateless. Components do not need to know about the router since everything is handled. | ||
|
||
### Dataflow: Two possible events | ||
#### Outbound changes: Changes from updated redux store | ||
When the redux state changes, we can then serialize it and save it in the url. This is handled by a middleware called `routerMiddleware`. | ||
|
||
This is reactive and won't change the redux store. | ||
|
||
#### Inbound changes: Changes from url hash updates | ||
The a component uses the `routerListener` to provide access to dispatching actions. It will perform a diff to see if an the store needs to be updated. If so, it will dispatch an event. | ||
|
||
If save data is not specified, the redux store should not be cleared. | ||
|
||
### User navigation via clicks on plain hash links | ||
User navigation should always occur through hash links. This is so that users can open links in new tabs as well as right clicking to copy the link. | ||
|
||
Although these events are user initiated, these are considered "inbound" changes since it is changing the hash which is outside of redux. | ||
|
||
### Routing actions and reducer | ||
The only code creating actions for routing.js should be the routerListener. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export const UPDATE_LOCATION = "UPDATE_LOCATION"; | ||
export function updateLocation(location) { | ||
return { | ||
type: UPDATE_LOCATION, | ||
location | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import {combineReducers} from 'redux'; | ||
import {UPDATE_LOCATION} from '../actions/routing'; | ||
import url from 'url'; | ||
|
||
const routing = combineReducers({ | ||
location, | ||
}); | ||
|
||
export default routing; | ||
|
||
function location(state, action) { | ||
if (typeof state === 'undefined') { | ||
// During first load, we want to reduce FOUC by bootstrapping here | ||
return url.parse(window.location.hash.substr(1)).pathname || ''; | ||
} | ||
if (action.type === UPDATE_LOCATION) { | ||
return action.location; | ||
} | ||
return state; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import {connect} from 'react-redux'; | ||
import React from 'react'; | ||
import url from 'url'; | ||
import {updateLocation} from '../actions/routing'; | ||
|
||
export const routerMiddleware = store => next => action => { | ||
return next(action); | ||
} | ||
|
||
class RouterHashListener extends React.Component { | ||
componentWillMount() { | ||
window.addEventListener('hashchange', this.hashChangeHandler.bind(this), false); | ||
} | ||
componentWillUnmount() { | ||
// Just doing our duty of cleanup though it's really not necessary | ||
window.removeEventListener('hashchange', this.hashChangeHandler.bind(this), false); | ||
} | ||
hashChangeHandler(e) { | ||
let oldUrlHash = url.parse(e.oldURL).hash || ''; | ||
let newUrlHash = url.parse(e.newURL).hash || ''; | ||
|
||
// The "real" url is inside the hash; | ||
let oldUrl = url.parse(oldUrlHash.substr(1)); | ||
let newUrl = url.parse(newUrlHash.substr(1)); | ||
|
||
if (oldUrl.pathname !== newUrl.pathname) { | ||
this.props.dispatch(updateLocation(newUrl.pathname)); | ||
} | ||
} | ||
render() { | ||
return null; | ||
} | ||
} | ||
|
||
export let RouterListener = connect(chooseState, dispatch => ({ dispatch }))((RouterHashListener)); | ||
function chooseState(state) { | ||
return { | ||
routing: state.routing | ||
}; | ||
} |