djsmith
djsmith

Reputation: 3087

How can I preserve a single query string value between routes in React Router?

I want to keep locale=en-US in the query string even when navigating between routes. I want the rest of my code to be blissfully ignorant of the locale=en-US query string value and automatically pass it along when I use a <Link>. How can I do this?

Upvotes: 2

Views: 1559

Answers (2)

djsmith
djsmith

Reputation: 3087

I learned that React Router does not provide this functionality out of the box, but one could create a custom Link component as suggested by @michal-cumpl like this:

import { Link as ReactRouterLink } from 'react-router'
import React, { Component } from 'react'
import merge from 'merge'
import url from 'url'

const QUERY_PARAMS_TO_PRESERVE = ['locale', 'foo', 'bar']

const makeToObj = (to, query) => {
  if (typeof to === 'string') {
    const u = url.parse(to, true)
    to = {
      pathname: u.pathname,
      query: u.query,
      hash: u.hash,
    }
  }

  if (to.query) {
    to.query = merge(query, to.query)
  } else {
    to.query = query
  }

  return to
}

class Link extends Component {
  render() {
    const currentQuery = url.parse(window.location.href, true).query
    const queryToPreserve = {}
    QUERY_PARAMS_TO_PRESERVE.forEach(x => queryToPreserve[x] = currentQuery[x])

    const to = makeToObj(this.props.to, queryToPreserve)

    return (
      <ReactRouterLink to={to}>
        {this.props.children}
      </ReactRouterLink>
    )
  }
}

export { Link }
export default Link

Note that this breaks when using third party tools that integrate with React Router, such as react-router-bootstrap's LinkContainer.

Upvotes: 0

Michal Cumpl
Michal Cumpl

Reputation: 1037

To achieve this, you can pass the following object to the Link to prop:

  • pathname: A string representing the path to link to.
  • query: An object of key:value pairs to be stringified.
  • hash: A hash to put in the URL, e.g. #a-hash.

Then you can write a component that will read and parse querystring from window.location.href and render Link.

https://github.com/ReactTraining/react-router/blob/master/docs/API.md#link

Upvotes: 1

Related Questions