Skip to content

Instantly share code, notes, and snippets.

@gaearon
Last active November 21, 2018 03:31
Show Gist options
  • Save gaearon/dfb80954a524709bcaf3bc584d9db11f to your computer and use it in GitHub Desktop.
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)
// 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);
@brettvitaz
Copy link

Thanks! This could help solve a problem I've experienced with <Link>s not updating.

p.s. you have two export default statements here.

@buzinas
Copy link

buzinas commented May 7, 2016

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