-
-
Save dleavitt/518b624d49c6bff7c2d7ee2782607ce3 to your computer and use it in GitHub Desktop.
mobx-react-router repro code
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
import React from 'react' | |
import { observer } from 'mobx-react' | |
import { RouteComponentProps, withRouter } from 'react-router-dom' | |
type WithRouterProps<P> = React.SFC<RouteComponentProps<any> & P> | |
| React.ComponentClass<RouteComponentProps<any> & P> | |
// makes the component an observer and also makes sure it rerenders on routing | |
// changes | |
export default function routeable<P>(Component: React.ComponentClass<P>) { | |
class RouteableObserver extends React.Component<P, any> { | |
render() { | |
return React.createElement(Component, this.props) | |
} | |
} | |
return withRouter( | |
observer(RouteableObserver) as WithRouterProps<P> | |
) as typeof RouteableObserver | |
} |
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
// https://codepen.io/pygmael/pen/BZwyGG | |
import React from 'react' | |
import { render } from 'react-dom' | |
import { observable } from 'mobx' | |
import { Provider, observer, inject } from 'mobx-react' | |
import { Router, Route, RouteComponentProps, NavLink, withRouter } from 'react-router-dom' | |
import { RouterStore, syncHistoryWithStore } from 'mobx-react-router' | |
import { History, createBrowserHistory } from 'history' | |
class DummyStore { | |
@observable maybe: boolean = true | |
} | |
const routerStore = new RouterStore() | |
const dummyStore = new DummyStore() | |
const history = syncHistoryWithStore(createBrowserHistory(), routerStore) | |
history.subscribe((location, action) => console.log(location.pathname)) | |
class Root extends React.Component<{}, {}> { | |
render() { | |
return ( | |
<Provider routing={routerStore} dummy={dummyStore}> | |
<Router history={routerStore.history}> | |
<Route component={Parent} /> | |
</Router> | |
</Provider> | |
) | |
} | |
} | |
@inject('dummy') | |
@observer | |
class Parent extends React.Component<RouteComponentProps<{}> & { dummy?: DummyStore }, {}> { | |
render() { | |
// This component is directly under the route so its NavLinks, etc always work | |
return ( | |
<div style={{ border: '1px white solid', margin: '8px', padding: '12px' }}> | |
Parent | |
<br /> | |
<NavLink to="/sandbox" activeStyle={{ color: 'red', textDecoration: 'none' }}>Sandbox</NavLink> | |
{' '} | {' '} | |
<NavLink to="/styleguide" activeStyle={{ color: 'red', textDecoration: 'none' }}>Styleguide</NavLink> | |
{' '} | |
<button type="button" onClick={() => this.props.dummy!.maybe = !this.props.dummy!.maybe}> | |
Toggle {this.props.dummy!.maybe ? 'TRUE' : 'FALSE'} | |
</button> | |
<Inter /> | |
</div> | |
) | |
} | |
} | |
// remove this observer annotation and routing works | |
// it doesn't seem to break store injection on the child either | |
@observer | |
class Inter extends React.Component<{}, {}> { | |
render() { | |
return ( | |
<div style={{ border: '1px green solid', padding: '12px' }}> | |
Inter | |
<Child /> | |
</div> | |
) | |
} | |
} | |
@inject('dummy', 'routing') | |
@observer | |
class Child extends React.Component<{dummy?: DummyStore, routing?: RouterStore}, {}> { | |
render() { | |
// The store is updated, but those updates don't make it to the Route/NavLink components | |
return ( | |
<div style={{ border: '1px red solid', padding: '12px' }}> | |
Child<br /> | |
<NavLink to="/sandbox" activeStyle={{ color: 'red', textDecoration: 'none' }}>Sandbox</NavLink> | |
{' '} | {' '} | |
<NavLink to="/styleguide" activeStyle={{ color: 'red', textDecoration: 'none' }}>Styleguide</NavLink> | |
<Route path="/sandbox" component={SandboxLabel} /> | |
<Route path="/styleguide" component={StyleguideLabel} /> | |
Toggle: {this.props.dummy!.maybe ? 'TRUE' : 'FALSE'} | |
<br /> | |
From RouterStore: {this.props.routing!.location!.pathname} | |
</div> | |
) | |
} | |
} | |
const SandboxLabel = (props: RouteComponentProps<{}>) => <div>SandboxLabel</div> | |
const StyleguideLabel = (props: RouteComponentProps<{}>) => <div>StyleguideLabel</div> | |
render(<Root />, document.getElementById('root')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment