I'm trying to replace a Backbone.Marionette App to React and am facing difficulty thinking about query params. I think I'm missing a really simple peace in understanding this pattern so I apologize if this question is totally nonsense. I would appreciate any support or just pointing me to some direction that I can google more specifically.
There's a /users
page which lists users and you can filter the users via search bar. So if you want to filter the users which contain 'joe' in their username, I would make a request to the server with query params like /users?username=joe
. In addition I am able to paginate by adding a page
parameter, too (/users?username=joe&page=1
).
If I only think about the functionality, the flow would probably be
joe
to the input element and clicks Search.Action
(like Action.getUser).Action
makes a request to the server and receives the resultsDispatcher
dispatches a function with the results payload to whomever (usually the Store
) is interested in the Action
.Store
's state changes with the new result received by the Action
Component
) re-renders by listening to the Store
's change.and it works as expected. However, I would like the Client to be able to bookmark the current filtered result and be able to come back to the same page some time later. This means I will need somewhere to save explicit information about the search term the Client made, which is usually the url (am I right?). So I will need to update the url with query parameters to save the search term (/users?username=joe&page=1
).
What I'm confused is where and when to update the url? What I can come up with right now are the 2 options below - and they don't seem to be clean at all.
joe
to the input element and clicks Search./users?username=joe&page=1
).Component
) receives the new params via this.props.params
and this.props.query
.Component
) fires an Action
like Action.getUser
depending on the query params it receives - in this case username=joe&page=1
.after this, it is the same as above
joe
to the input element and clicks Search.Action
(like Action.getUser).Action
makes a request to the server and receives the resultsDispatcher
dispatches a function with the results payload to whomever (usually the Store
) is interested in the Action
.Store
's state changes with the new result received by the Action
Component
) re-renders by listening to the Store
's change. And somehow (I don't know how, yet) updates its url depending on its props
(like this.props.searchusername
, and this.props.searchpage
) What is the best practice on handling query params? (or this may not be specific to query params) Am I completely misunderstanding the design pattern or architecture? Thanks in advance for any support.
Some articles I've read
To pass in query parameters, we just add them to the Link s to props as usual. For example, we can write the following: We first defined the useQuery Hook to get the query parameters of the URL via the URLSearchParams constructor. We get the useLocation() s search property.
Get a single Query String value location.search object: import React from 'react'; import { useSearchParams } from 'react-router-dom'; const Users = () => { const [searchParams] = useSearchParams(); console. log(searchParams); // ▶ URLSearchParams {} return <div>Users</div>; };
In react router v4, we can access the query param data from a URL using the props. location.search property. In class-based components, you can access it like this.
To add multiple parameters with React Router, we can get the URL parameters from the useParams hook. <Route path="/:category/:id" exact component={ItemDetails} />; to add the category and id parameters to the Route . We call useParams to return an object with the id and category parameters.
I would consider best practice to be the submit button only setting the location query (username). The rest should be taken care by the main react component that is assigned as router component. By this, you can be sure that anytime one revisits or shares the url, they can get the same results. And this is very generic too.
Something like this:
let myQuery = this.props.location.query; if (myQuery.username) { let theUser = myQuery.username; this.setState({ userName = myQuery.username }); } else { this.setState({ userName = false //Show All }); }
And then use this state "userName" to send to the server to search with. By this way, you will not need to iterate the code of the component that takes care of listing users since server already sends the relevant data.
In my experience with using location queries in React, I have been very content with their reactivity cycles and performance. I'd highly recommend keeping every different app state in relevance with the url.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With