I’m currently learning how to use function components in react and got a bit of a timing problem. As it seems, the event that should trigger a rerender is called between the rendering of the component and the call to the useEffect hook. Is there any delay between those two that would allow an async event to be executed? And how would I prevent this “gap”? (I do not remember about every having such a problem with class components and the componentDidMount function for registering my eventListener back then).
Given this component (with very simplified types and logic):
export default function CounterDisplay(): React.JSX.Element {
const [lastEventInstance] = useEvent('counter_changed_event');
const counter = lastEventInstance ? lastEventInstance.counter : 0;
console.log('Start rendering CounterDisplay: ', counter);
return (
<div>{counter}</div>
);
}
with this custom event hook:
export function useEvent(eventName: string) {
const [lastEventInstance, setEventInstance] = useState<undefined | {counter: number}>(undefined);
useEffect(() => {
function handleEvent(event: EventDefinition) {
console.log('Pushing new event into the state');
setEventInstance(event);
}
console.log('Listening to event ' + eventName);
EventManager.addEventListener(eventName, handleEvent);
return () => {
console.log('Stop listening to event');
EventManager.removeEventListener(handleEvent);
};
}, [lastEventInstance]);
return [lastEventInstance];
}
I get this output in the console:
> Start rendering CounterDisplay: 0
> EventManager notifies event "counter_changed_event" with data {counter: 1}
> Listening to event counter_changed_event
while the html output keeps showing the value 0.
And to be clear: Yes, the {counter: 1} object is an entirely new object that is definetely even shallowly different from the previous.
I hope someone can help me with this, as this is at the moment a nasty race condition.