Hi everyone
I'm pretty new to React. Although i'm going fine with simple projects, there is now an issue with a complex one. I'm using Redux, with Redux Thunk and some custom hooks.
I have this hook, inside a custom hook
useEffect(() => {
if (environment.dateStart) {
if (environment.dateEnd) {
//props.onUpdateDaysConfig([])
autoClick(environment.dateStart)
autoClick(environment.dateEnd)
} else {
autoClick(environment.dateStart)
}
}
}, [props.daysConfig.length]);
const autoClick = dateString => {
const sDate = new Date(dateString);
const q = props.daysConfig.filter(day => day.day === sDate.getDate() && day.month === sDate.getMonth() + 1 && day.year === sDate.getFullYear());
if (q.length > 0) {
onDaySelect(q[0])
}
}
props.daysConfig
is a state from a Redux store, holding an array of objects with a structure like the following (pseudo code):
- day (int)
- month (int)
- year (int)
- classes (string[])
- data (object/any)
onDaySelect
is defined this way:
const onDaySelect = data => {
if (JSON.stringify(data.data) === '{}') {
handleClickOutsideRates(data)
} else {
handleClickInRates(data)
}
}
where handleClickOutsideRates
and handleClickInsideRates
reside on another custom hook; they perform calculations and then trigger some Redux updates. Both of these depend on this, defined on the same hook and available to both:
const alreadySelectedDays = props.daysConfig.filter(d => d.classes.indexOf(constants.selectedClass) > -1);
(constants is an import from another file, defining a set of strings).
This array's length determines what handleClickOutsideRates
and handleClickInsideRates
will do.
This looks where things break up. If i call onDaySelect
from a click, it works just as i expect, in every situation. If i do the same from that useEffect, only the first one works correctly; then the second one is tricked, because alreadySelectedDays
is still evaluated as an empty array, no matter what. It's like they get executed at the same moment, or maybe the second one starts before the first gets completed. Anyways, it is clear that i'm missing something about hooks, or maybe Redux itself.
I'm certainly going to move all of that logic to the store, but i would like to know how things are working. Could anyone explain me why is this happening? Thank you.
EDIT: i was able to achieve the desired result this way:
const freeForSecond = useRef(false)
useEffect(() => {
if (environment.dateStart) {
autoClick(environment.dateStart)
}
return () => {
freeForSecond.current = true
};
}, [props.daysConfig.length]);
useEffect(() => {
if (environment.dateEnd) {
if (freeForSecond.current)
autoClick(environment.dateEnd)
}
}, [freeForSecond.current])
This ensures the second autoClick
being called after, granting it to work.
I don't like it. I feel like i'm misusing the returned callback, since i'm doing no cleaning operations in there. Plus, although i forced it to work, i still don't know why it didn't work the way it was.
Top comments (3)
I think we should try Redux Toolkit Query (RTKQ) as introduced in Reedux tutorial : redux.js.org/tutorials/essentials/...
which is covered more detail in its doc : redux-toolkit.js.org/rtk-query/ove... and subsequent chapters of the doc.
this sounds like either a stale closure or an inaccurate dependency array -- im happy to review a runnable sample if that's helpful
Thanks for your reply. I'm sure that dependency array is no good at all. I'll later share a sample so you can review it