Reputation: 1146
For some reason, it seems that the useMemo hook is executing before the useEffect hook, directly above it. I believe this is so because I am receiving an error:
TypeError: Cannot read property 'timestamp' of undefined
this error points to the datum.timestamp
in the dependency array for the last useEffect hook and occurs whenever is_paused
changes from false => true
.
The problem as I see it, is that the useMemo hook is trying to get an item from an empty array, an array which should have been set by the useEffect before it.
I did some logging, and indeed, I see the log in the useMemo, but not the useEffect.
const [position, setPosition] = useState(MAX_HISTORY - 1);
const [data, setData] = useState<ExData[]>(new Array(MAX_HISTORY).fill({ content: {} }));
const paused_data_ref = useRef<ExData[]>([]);
useEffect(() => {
const listener = (d: ExData) => {
const new_data = data.slice(1);
new_data.push(d);
setData(new_data);
};
addListener(props.event_key, listener);
return () => {
removeListener(props.event_key);
};
});
useEffect(() => {
paused_data_ref.current = is_paused ? [...data] : [];
if (is_paused) {
console.log('copy data array');
}
}, [is_paused, data]);
const datum = useMemo(() => {
if (is_paused)
console.log({
position,
data: paused_data_ref.current[position],
arr: paused_data_ref.current
});
return is_paused ? paused_data_ref.current[position] : data[MAX_HISTORY - 1];
}, [is_paused, position, data]);
useEffect(() => {...}, [datum.timestamp])
Upvotes: 2
Views: 1676
Reputation: 6529
You are correct, the function passed to useEffect
is called after the function passed to useMemo
.
According to the React docs:
The function passed to useEffect will run after the render is committed to the screen.
This means that all useEffect
calls will happen after the other functions in your component (including a function passed to useMemo
), even if the useEffect
is placed earlier in the component.
https://reactjs.org/docs/hooks-reference.html
Upvotes: 5