相关文章推荐
逃跑的企鹅  ·  647 webpack中使用 ...·  2 天前    · 
爱看球的伤疤  ·  vue.js - vuejs plugin ...·  1 年前    · 
鼻子大的松鼠  ·  SQL 如果A欄位是NULL ...·  1 年前    · 
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 the response. This is what I actually was doing and works when there is only one child. I've updated the question to include more details of the issue I'm facing. Sorry for the incomplete question in the first place.
– Sachin
                Mar 29, 2021 at 6:09
                You may need to add search as the child useEffect dependency, not sure if it will fix your bug, haven't tested it.
– vuongvu
                Mar 29, 2021 at 6:21
        

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.