Realtime lets your app update instantly when data changes. React hooks make it easy to add realtime updates in your React app.
Realtime with React hooks in Supabase
import { useEffect, useState } from 'react'; import { createClient } from '@supabase/supabase-js'; const supabase = createClient('your-url', 'your-anon-key'); function useRealtime(tableName) { const [data, setData] = useState([]); useEffect(() => { const subscription = supabase .from(tableName) .on('INSERT', payload => { setData(current => [...current, payload.new]); }) .subscribe(); return () => { supabase.removeSubscription(subscription); }; }, [tableName]); return data; }
Replace 'your-url' and 'your-anon-key' with your Supabase project details.
The hook listens for new rows inserted into the specified table.
messages state.const messages = useRealtime('messages');useEffect(() => {
const subscription = supabase
.from('tasks')
.on('UPDATE', payload => {
console.log('Task updated:', payload.new);
})
.subscribe();
return () => supabase.removeSubscription(subscription);
}, []);This React component shows live messages from the 'messages' table. It fetches existing messages and updates instantly when new messages arrive.
import React from 'react'; import { createClient } from '@supabase/supabase-js'; const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key'); function useRealtime(tableName) { const [data, setData] = React.useState([]); React.useEffect(() => { // Fetch initial data supabase.from(tableName).select('*').then(({ data }) => { setData(data || []); }); // Subscribe to new inserts const subscription = supabase .from(tableName) .on('INSERT', payload => { setData(current => [...current, payload.new]); }) .subscribe(); return () => { supabase.removeSubscription(subscription); }; }, [tableName]); return data; } export default function Messages() { const messages = useRealtime('messages'); return ( <div> <h2>Live Messages</h2> <ul> {messages.map(msg => ( <li key={msg.id}>{msg.text}</li> ))} </ul> </div> ); }
Always clean up subscriptions in useEffect cleanup to avoid memory leaks.
Supabase realtime works best with tables that have primary keys.
You can listen to other events like 'UPDATE' or 'DELETE' by changing the event type.
Realtime with React hooks lets your app update instantly when data changes.
Use useEffect to subscribe and clean up realtime events.
Supabase makes it easy to listen to database changes and update React state.
Practice
Solution
Step 1: Understand Realtime with React hooks
Realtime with React hooks allows the app to listen for changes in the database and update the UI immediately.Step 2: Identify the main purpose
The main goal is to keep the app data fresh without manual refresh by updating instantly on data changes.Final Answer:
To update the app instantly when data changes in the database -> Option CQuick Check:
Realtime updates = instant app data refresh [OK]
- Confusing realtime with styling or authentication
- Thinking it fetches data only once
- Assuming it handles user login
Solution
Step 1: Recall React hooks for side effects
useEffect is designed to run code on component mount and clean up on unmount, perfect for subscriptions.Step 2: Match with Supabase realtime subscription
Supabase realtime subscriptions need to be set up and cleaned up properly, which useEffect handles well.Final Answer:
useEffect -> Option AQuick Check:
Subscriptions need useEffect [OK]
- Using useState for subscriptions
- Confusing useMemo with side effects
- Thinking useContext handles subscriptions
const [messages, setMessages] = useState([]);
useEffect(() => {
const subscription = supabase
.from('messages')
.on('INSERT', payload => {
setMessages(current => [...current, payload.new]);
})
.subscribe();
return () => {
supabase.removeSubscription(subscription);
};
}, []);What happens when a new message is inserted into the 'messages' table?
Solution
Step 1: Analyze the subscription callback
On 'INSERT' event, the callback adds the new message (payload.new) to the current messages array using setMessages.Step 2: Understand state update behavior
setMessages uses a function to append the new message, preserving existing messages and adding the new one.Final Answer:
The new message is added to the messages state array -> Option AQuick Check:
INSERT event appends new message [OK]
- Thinking state resets instead of appending
- Assuming subscription stops on insert
- Believing setMessages usage is incorrect here
useEffect(() => {
supabase
.from('tasks')
.on('UPDATE', payload => {
setTasks(tasks.map(t => t.id === payload.new.id ? payload.new : t));
});
}, []);But the app does not update when tasks change. What is the likely problem?
Solution
Step 1: Check subscription setup
The code calls .on() but does not call .subscribe(), so the subscription is never activated.Step 2: Confirm event type and state update
'UPDATE' is valid and setTasks usage is correct; empty dependency array is appropriate here.Final Answer:
The subscription is missing the .subscribe() call -> Option DQuick Check:
Missing .subscribe() means no updates [OK]
- Forgetting .subscribe() after .on()
- Thinking event type 'UPDATE' is wrong
- Misusing setTasks function
- Changing dependency array unnecessarily
Solution
Step 1: Understand multiple event subscriptions
To listen to both INSERT and DELETE, create two subscriptions with .on('INSERT') and .on('DELETE').Step 2: Manage subscriptions lifecycle
Inside useEffect, subscribe to both and return a cleanup function that removes both subscriptions to avoid memory leaks.Final Answer:
Use two separate subscriptions inside one useEffect, each with .subscribe(), and remove both on cleanup -> Option BQuick Check:
Multiple subscriptions + cleanup = correct approach [OK]
- Ignoring DELETE events
- Not cleaning up subscriptions
- Subscribing outside useEffect causing leaks
- Using only one event subscription
Ready to prove it?
Pass the test and this pattern moves unknown
