Last active
November 21, 2018 03:31
-
-
Save gaearon/dfb80954a524709bcaf3bc584d9db11f to your computer and use it in GitHub Desktop.
Drop-in replacement for React Router <Link> that works with React Redux optimizations (https://github.com/reactjs/react-router/issues/470)
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
// While I claim this is a drop-in replacement, it is a little bit slower. | |
// If you have hundreds of links, you might spend a few more milliseconds rendering the page on transitions. | |
// KNOWN ISSUES WITH THIS APPROACH: | |
// * This doesn't work great if you animate route changes with <TransitionGroup> | |
// because the links are going to get updated immediately during the animation. | |
// * This might still not update the <Link> correctly for async routes, | |
// as explained in https://github.com/reactjs/react-router/issues/470#issuecomment-217010985. | |
// However, you might find it useful for the rest of the use cases where you want <Link>s to re-render | |
// on route changes while preserving the optimizations that connect() from React Redux gives you. | |
// More info: https://github.com/reactjs/react-router/issues/470 | |
// This solution is inspired by this comment by @geekyme: https://github.com/reactjs/react-router/issues/470#issuecomment-198440124 | |
import React, { Component } from 'react'; | |
import { withRouter, Link as RouterLink } from 'react-router'; | |
export default class Link extends Component { | |
componentDidMount() { | |
this.unsubscribe = this.props.router.listen(nextLocation => { | |
if (this.location !== nextLocation) { | |
this.location = nextLocation; | |
this.forceUpdate(); | |
} | |
}); | |
} | |
componentWillUnmount() { | |
this.unsubscribe(); | |
} | |
render() { | |
return <RouterLink {...this.props} />; | |
} | |
} | |
export default withRouter(Link); |
For anyone who's already using React Router Redux, I made a pretty simple Link
component and it's working on two apps I'm working on:
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
const ReduxLink = ({ className = '', activeClassName, to, path, children }) => {
let finalClassName = className.split(' ');
if (activeClassName && path === to) {
finalClassName.push(activeClassName);
}
return (
<Link to={to} className={finalClassName.join(' ')}>
{children}
</Link>
);
};
export default connect(
(state, ownProps) => Object.assign({}, ownProps, { path: state.routing.locationBeforeTransitions.pathname })
)(ReduxLink);
Btw, it can replace both Link
and IndexLink
components.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks! This could help solve a problem I've experienced with
<Link>
s not updating.p.s. you have two
export default
statements here.