Description
Suppose I have a component like:
import {browserHistory} from 'react-router'
const LinkButton = props => (
<Button value={props.to} onPush={browserHistory.push}>
{props.label}
</Button>
)
It throws when shallow rendered in a non-browser env, since browserHistory
is undefined. It also throws if I access context.router.push
, since it just proxies the history passed to Router
. This is a big pain for unit testing.
I could wrap history at the top level, but I'd much rather import history directly from the library; isn't that the point of exposing the singleton?
// history.js:
export default isBrowserEnv() ? browserHistory : createMemoryHistory()
// LinkButton.js:
import history from '../history' // ew
I could pass a conditional history to Router
, but then I'd always have to rely on context.router
which is verbose and prevents me from writing functional components like LinkButton
, above.
const history = isBrowserEnv() ? browserHistory : createMemoryHistory()
const router = <Router history={history} routes={routes} />
I could just do this everywhere, but it's verbose, repetitive, and doesn't let me test routing:
<Button value={props.to} onPush={browserHistory ? browserHistory.push : noop}>
One option on the library side is to have the history singleton return more than undefined
in non-browser envs. Even just implementing the history interface using noops would at least prevent components throwing. Has this been considered? Is there a better recommended approach?
(I considered this more like a feature request / API discussion than a question, so I posted here rather than StackOverflow, but feel free to redirect me if you disagree!)