I have a general concept, and I would like to know if it is a good approach and if it will work. Let’s assume I have two hooks. Hook #1 is useClient
, which has a state called range
. I expose this state to a UI component and allow the UI to set its state. I also have another hook, Hook #2, called useOrders
, where I import the range
state from the useClient
hook. I then use the useEffect
hook to detect any changes in the range
state and, if there is a change, fetch data.
My question is: If the range
state changes in the useClient
hook, will the useEffect
in the useOrders
hook run? How is this state propagation and effect triggering achieved in React hooks?
Any insights or suggestions on this approach would be highly appreciated.
Here are the examples of my hooks:
UseClient Example:
const useClient = () => {
const { id } = useParams();
const [range, setRange] = useState({
from: new Date().toISOString(),
to: new Date().toISOString(),
});
return {
range,
setRange,
};
};
export default useClient;
UseOrders Example:
import useClient from './useClient';
const useOrders = () => {
const { range } = useClient();
const { id } = useParams();
const [orders, setOrders] = useState([]);
const [pagination, setPagination] = useState({
page: 1,
limit: 10,
total: 0,
totalPages: 1,
});
const fetchOrders = useCallback(async () => {
const params = {
page: pagination.page,
limit: pagination.limit,
from: range.from,
to: range.to,
};
try {
const response = await api.get(`order/getOrders/${id}`, { params });
if (response.data.success) {
setOrders(response.data.orders);
setPagination((prev) => ({
...prev,
total: response.data.pagination.total,
totalPages: response.data.pagination.totalPages,
}));
}
} catch (error) {
console.error('Fetching Orders error:', error);
}
}, [id, pagination.page, pagination.limit, range]);
useEffect(() => {
fetchOrders();
}, [fetchOrders, range, pagination.page, pagination.limit]);
return {
orders,
pagination,
setPagination,
};
};
export default useOrders;
2
Answers
as @Matt Morgan mentioned, context provider is the solution for this
No. You haven’t illustrated the UI component in which you set state in
useClient
, but based on the rest of the code, the answer is no.Your UI component (setting the range) will be bound to a different instance of the state within
useClient
— its own copy, in other words.I wouldn’t expect any relationship between the state of
useClient
you call in one component and the instance you call from a different component.Of course, this would be different if the state were stored in a shared ancestor, like a context provider.
Here’s the explainer from up-to-date version of react.dev, which explains it slightly differently.