Skip to content

Instantly share code, notes, and snippets.

@nickydonna
Created September 22, 2016 19:53
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickydonna/3d76397a92551f449637590bf0413133 to your computer and use it in GitHub Desktop.
Save nickydonna/3d76397a92551f449637590bf0413133 to your computer and use it in GitHub Desktop.
A Contoller ReactRouter for v4
/* @flow */
import BrowserHistory from 'react-history/BrowserHistory'
import {Push, Replace} from 'react-history'
import React, {Component} from 'react'
import {StaticRouter} from 'react-router'
type RouterProps = {
onChange: (action: string, location: Object) => void,
pathname: string,
navigation?: 'PUSH' | 'REPLACE',
};
/**
* A router that exposes ways to connect to store such as Redux
*/
class ControlledRouter extends Component {
props: RouterProps
static defaultProps: {
navigation: string
}
render() {
const { navigation, pathname, onChange } = this.props
return (
<BrowserHistory key={pathname} > // github.com/yahoo/react-intl/issues/234#issuecomment-163366518
{({ history, action, location }) => {
const pathnameChanged = location.pathname !== pathname
if (pathnameChanged) {
setImmediate(() => onChange(action, location))
}
return (
<StaticRouter
action={action}
location={location}
onPush={history.push}
onReplace={history.replace}
blockTransitions={history.block}
>
{pathnameChanged && navigation === 'PUSH' &&
<Push path={pathname}/>
}
{pathnameChanged && navigation === 'REPLACE' &&
<Replace path={pathname}/>
}
</StaticRouter>
)
} }
</BrowserHistory>
)
}
}
ControlledRouter.defaultProps = {
navigation: 'PUSH'
}
export default ControlledRouter
@nickydonna
Copy link
Author

nickydonna commented Sep 22, 2016

Based on @Stedia's gist https://gist.github.com/steida/16da36887e6e6b466e12ba3a4ae6ce87

We haven't tested it, we will do it tomorrow and fix it if necessary.

The idea is to make a connected router that can dispatch actions when the route changes and can react to state changes

Usage with Redux:

const mapStateToProps = state => {
  pathname: state.router.pathname
}

const mapDispatchToProps = dispatch => {
  onChange: (action, pathname) => {
    dispatch({ type: 'LOCATION_CHANGED', action, pathname })
  }
}

connect(
  mapStateToProps,
  mapDispatchToProps,
)(ControlledRouter)

@nickydonna
Copy link
Author

The BACK, FORWARD and POP actions need internal state to avoid infinite history changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment