Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have a parent component, that renders two child components. The parent is using useLocation to read query parameters from location.search. The children have logic to add some query parameter to the url. So once a child completes its render, it adds a query parameter to the url, but the value of useLocation in the parent only has the query param from the second child. The update made by the first child seems to have been overwritten.
const Parent = () => {
const location = useLocation();
useEffect(() => {
console.log(location.search)
}, [location.search]);
return (
<Child1 />
<Child2 />
const Child1 = () => {
const {search} = useLocation();
const {push} = useHistory();
useEffect(() => {
// modify query parameter here
const query = queryParams.parse(search);
query.lang = 'en';
push({
search: queryParams.stringify(query)
}, [])
return (<div>Child1</div>)
const Child2 = () => {
const {search} = useLocation();
const {push} = useHistory();
useEffect(() => {
// modify query parameter here
const query = queryParams.parse(search);
query.q = 'sample';
push({
search: queryParams.stringify(query)
}, [])
return (<div>Child2</div>)
I expected first child to update url to ?lang=en
and second child to update it to ?lang=en&q=sample
. But what happens is first child updates it to ?lang=en
and second child updates it to ?q=sample
. They are unaware of each others changes even though they are both using useLocation hook. And the parent always has only the second child's update.
What's the mistake here? Also, is there a recommended way of doing something like this? The solution that worked for me was to use window.location.search
in the childrens' useEffect so that when the second child is rendering, it is aware of the URL change made by the first child. This change is not detected by the useLocation hook. I would like to really understand the workings of this hook. Any help is appreciated. Thanks :)
Here is what I'd do:
I'm having these imports:
import { useLocation, useHistory } from "react-router-dom";
import queryString from "query-string";
Child
const Child = () => {
const { search, pathname } = useLocation();
const { push } = useHistory();
// assume you want to add `lang` to query param
useEffect(() => {
const query = queryString.parse(search);
query.lang = "en";
push({ pathname, search: queryString.stringify(query) });
}, [search]);
return <div>Child</div>;
Parent
const Parent = () => {
const { search, pathname } = useLocation();
useEffect(() => {
const query = queryString.parse(search);
console.log(query.lang);
}, [search]);
return (
<Child />
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.