Connected-react-router: Array in query params

Created on 10 Dec 2019  路  5Comments  路  Source: supasate/connected-react-router

In my app I store array of params in query string like this ?foo=bar&foo=qux. When I want to get these values I am not able to do it using connected-react-router because it stores only the last value in query field.

router = {
  location: {
    search: '?foo=bar&foo=qux',
    query: {
      foo: 'qux'
    }
  }
}

So in order to access these values I use parse from query-string lib. It would be more convenient if I could get these values directly from router reducer.

Is this expected behavior or should I create a PR to address this issue?

All 5 comments

It was not a good idea
In my case search already contains a query parameter
Parsing or not the search should be optionnal :)

@nickvoronin-ellation I think router.location.query only intends to address the most common case, where keys are unique. Personally I ignore it and parse using the browser-provided URLSearchParams. You can even write your own selector to make it easy:

import {getSearch} from 'connected-react-router'
import {createSelector} from 'reselect'

const getUSP = createSelector(
  [getSearch],
  search => new URLSearchParams(search),
)

and then use that in your connected components, or put it into a context.

@agriffis this is a very elegant solution, I like it a lot, thank you!

@supasate Maybe we should at least describe this case in the FAQ section so that newcomers would have an idea how to deal with such a case?

With the former library, react-router-redux, you could use history-query-enhancer on your history before passing it to to configureStore, like this:

import { createBrowserHistory } from 'history';
import withQuery from 'history-query-enhancer';
import queryString from 'query-string';

const history = withQuery(queryString)(createBrowserHistory());

And have location working with query parsed by your library of choice.

@agriffis:
The problem is that connected-react-router parses the location.search string itself and saves it into the query property of location in the store, so it overwrites the query parsed by queryString. It's still there in props.location.query if you use withRouter(), but not in state.router.location.query, so you can't use that one if you need query.

What would be great is if you could pass an option so it uses the existing query instead of trying to parse location.search itself, so we wouldn't have to use both connect and withRouter in the same component.

I could write a PR for it myself, if @supasate would be willing to accept it.

Fixed in #396.

Was this page helpful?
0 / 5 - 0 ratings