Home > OS >  React Child Component Api Calling Two Times (strict mode is off)
React Child Component Api Calling Two Times (strict mode is off)

Time:12-20

Here, are three components User Details and its two Childs are UserSpecificData1 and UserSpecificData2.

In User Details component im getting User Details with userId by api calling.

Now i declared Two childs by passing that user id.

Problem is: Two child api is calling two times! Why? React strict mode is off.

Note: I noticed that child components are rendering two times by console.log

`

export const UserDetails = () => {
  const params = useParams(); // {userId: 223}
  useEffect(() => {
    if(params?.userId){
       getCustomerDetails(params.userId) // 223
}
  }, [params.userId]);

  return (
    <div>
      <UserSpecificData1 userId={params.userId}/>
      <UserSpecificData2 userId={params.userId}/>
    </div>
  );
};


// Component 1

const UserSpecificData1 = props => {
  const [currentPage, setCurrentPage] = useState(0);
  const [filteredBy, setFilteredBy] = useState({});
  const [sortBy, setSortBy] = useState('ASC');

  useEffect(() => {
    getSpecificDataOne({
      id: props.userId, //223
      filteredBy: filteredBy,
      page: currentPage,
      size: 10,
      sortBy: sortBy,
    })
  }, [sortBy, currentPage, filteredBy]);

  return <div>
  </div>

};


// Component 2

const UserSpecificData2 = props => {
  const [currentPage, setCurrentPage] = useState(0);
  const [filteredBy, setFilteredBy] = useState({});
  const [sortBy, setSortBy] = useState('ASC');

  useEffect(() => {
    getSpecificDataTwo({
      id: props.userId, //223
      filteredBy: filteredBy,
      page: currentPage,
      size: 10,
      sortBy: sortBy,
    })
  }, [sortBy, currentPage, filteredBy]);

  return <div>
  </div>

};


`

CodePudding user response:

Hey i just reviewed your code and i came up with conclusion that you have to add a condition on both child useEffect where api is being called and check for prop.userId exist or not and don't forgot to passed it as dependency array.

useEffect(()=>{
 if(props?.userId){
    getSpecificDataTwo({
     id: props.userId, //223
     filteredBy: filteredBy,
     page: currentPage,
     size: 10,
     sortBy: sortBy,
    });
 }

},[sortBy, currentPage, filteredBy,props.userId]);

let me know if this works for you otherwise we will go for another way.

CodePudding user response:

My guess is that the code isn't quite complete?

So I'm assuming you also have a [content, setContent] somewhere in the first component UserDetails - and if so, it'll first render the child components, and then, if params.userId exists, after the content has loaded it'll re-render.

A couple of ways to stop this, probably the best being surrounding your child components with { content && <Child 1 />...}

So complete code would be:

export const UserDetails = () => {
  const params = useParams(); // {userId: 223}
  const [content, setContent] = useState(null)

  useEffect(() => {
    if(params?.userId){
       getCustomerDetails(params.userId)
          .then(result => {
             setContent(result);
          }) // 223
    }
  }, [params.userId]);

  return (
    <div>
      { content &&
         <>
            <UserSpecificData1 userId={params.userId}/>
            <UserSpecificData2 userId={params.userId}/>
         </>
      }
    </div>
  );
};

Personally I'd probably also put the userId into a hook and use that as the check, up to you which works better.

  • Related