@ryvora/react-use-effect-event
v2.0.0
Published
useEffect + event = ❤️. Always up-to-date event handlers for effects in React!
Maintainers
Readme
use-effect-event 🤝 useEffect & Event
Hi 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!
The Problem
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. 😬
The Solution
use-effect-event (or useEvent) provides a stable function reference that internally always calls the latest version of your event handler logic.
Conceptual Usage (based on React RFC for useEvent)
import { useEffectEvent } from '@ryvora/react-use-effect-event'; // Or `useEvent`
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 deps
console.log(`New message with theme ${theme}:`, 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 <div>Messages: {messages.join(', ')}</div>;
}Keep your effects clean and your dependencies minimal! ✨🧼
