useEffect + event = ❤️. Always up-to-date event handlers for effects in React!
npm install @ryvora/react-use-effect-eventHi Effect Optimizer! ⚡
The use-effect-event hook (sometimes named useEvent or similar, as proposed by the React team) helps you define an event handler or callback inside a useEffect that can access the latest props and state without needing to be included in the effect's dependency array.
It's like giving your useEffect a special, always-up-to-date lens 👓 to see the current component state, without triggering the effect every time that state changes!
Sometimes, a useEffect needs to call a function that depends on props or state. If you include that function in the dependency array, the effect re-runs whenever the function reference changes (which is often on every render if it captures props/state).
If you omit it, you get a stale closure and the function uses old props/state values. 😬
use-effect-event (or useEvent) provides a stable function reference that internally always calls the latest version of your event handler logic.
useEvent)``tsxuseEvent
import { useEffectEvent } from '@ryvora/react-use-effect-event'; // Or
import React, { useState, useEffect } from 'react';
function ChatRoom({ roomId, theme }) {
const [messages, setMessages] = useState([]);
// This function would normally need to be in the effect's deps, or cause stale closures.
const onMessage = useEffectEvent((newMessage) => {
// Can access latest theme and messages without them being in depsNew message with theme ${theme}:
console.log(, newMessage);
setMessages((prevMessages) => [...prevMessages, newMessage]);
});
useEffect(() => {
// Subscribe to chat messages for roomId
const connection = createConnection(roomId);
connection.on('message', (msg) => {
onMessage(msg); // Call the stable event handler
});
return () => connection.disconnect();
// Only re-runs if roomId changes, not if theme or messages change!
}, [roomId]);
return
Keep your effects clean and your dependencies minimal! ✨🧼