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.