I am using React and I have a parent component that holds several other children components and children components have props that are fetched in a parent component from the database and given as props. For example, this is the parent component:
const OrderDetails = (props: Props) => {
const [trigger, setTrigger] = useState(false);
const [renderChildren, setRenderChildren] = useState(false);
const [order, setOrder] = useState<
(Order & { userClients: OrderClient[] }) | null
>(null);
useEffect(() => {
const getData = async () => {
const orderResponse = await getOrder();
if (orderResponse) {
setOrder(orderResponse.data);
setRenderChildren((prev) => !prev);
}
};
getData();
}, [trigger]);
if (!order) return null;
return (
<div>
<child1 order={order} renderChildren={renderChildren} />
<child2 order={order} renderChildren={renderChildren} setTrigger={setTrigger} />
</div>
)
So let me explain further the above code:
-
OrderDetails fetches data during useEffect and only refetches if trigger has been updated. This is necessary as children would manipulate database, change some status and the fetched data by OrderDetails is no longer valid
-
child2 has a button that does that, it does some action that manipulates with database. Also child2 (depending on ther order) could display different data and have different button functionalities. So whenever we render child2, we need up to date order details from the database.
-
Upon pressing button in child2, it uses
setTriggger((prev) => !prev)
and this triggers a rerender of the OrderDetails and it refetches the data. Now so far so good -
Then we need to rerender child1 and child2 so that they would display the latest data and as I said, child2 also depend on the latest data to display correct names and functionalities of the button. Therefore I have also added
setRenderChildren
at useEffect of OrderDetails that would trigger useEffect call on child1 and child2 (they have useEffect with a dependency onrenderChildren
).
This is working but I feel this is not a proper way to do this. Can you give me any advice?
So far before coming up with this solution I have tried:
- Creating a context that would hold trigger and renderChildren but essentially it is the same thing. May be better in a sense that I do not have to propogate props down the children but the same
Roger Atmanolv is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.