Reputation: 3087
I need to update a useCallback hook on a certain event that is emitted by eventEmitter3. Right now I update a local state with the current time to trigger the useCallback. That works but looks crazy complicated. Is there a better solution?
const [referencesDidChange, setReferencesDidChange] = useState(0);
useEffect(() => {
const referencesChange = () => {
setReferencesDidChange(new Date().getTime());
};
eventEmitter.on(Events.ReferencesChange, referencesChange);
return () => {
eventEmitter.removeListener(Events.ReferencesChange, referencesChange);
};
}, []);
const renderLeaf = useCallback(props => <Leaf {...props} />, [referencesDidChange]);
Upvotes: 1
Views: 1109
Reputation: 3087
As Rico Kahler pointet out in the comments in his answer, there is a react docs example on this, which results in the much clearer:
const [referencesDidChange, setReferencesDidChange] = useReducer(x => x + 1, 0);
useEffect(() => {
eventEmitter.on(Events.ReferencesChange, setReferencesDidChange);
return () => {
eventEmitter.removeListener(Events.ReferencesChange, setReferencesDidChange);
};
}, []);
const renderLeaf = useCallback(props => <Leaf {...props} />, [referencesDidChange]);
Upvotes: 0
Reputation: 19302
I would suggest pulling the most recent values via a ref instead of updating the callback.
In general, with callbacks, you don't need to update them if you pull values at the time of running them. I'm not suggesting that you always do this by default but in certain cases it can clean things up if you rearchitect to pull on invocation if you can.
const someRef = useRef(null);
useEffect(() => {
someRef.current = someChangingValue;
}, [someChangingValue]);
const renderLeaf = useCallback(() => {
const latestValues = someRef.current;
// use latest values…
}, []);
Upvotes: 2