Membangun Komponen Obrolan Waktu Nyata
Tampilkan pesan langsung dalam daftar obrolan yang dapat digulir menggunakan event WebSocket dan status React.
Membangun Komponen Obrolan Waktu Nyata adalah pelajaran React Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar React Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus React Academy mencakup 4 pelajaran total.
Arsitektur Komponen Obrolan
Obrolan waktu nyata memiliki tiga bagian: daftar pesan (tampilan), masukan pesan (pengiriman), dan lapisan koneksi WebSocket/Socket.IO. Simpan logika soket dalam kait kustom.
Bentuk Data Pesan
Tentukan antarmuka TypeScript untuk pesan obrolan agar keamanan tipe komponen tetap terjaga secara menyeluruh.
interface Message {
id: string;
text: string;
sender: string;
timestamp: number;
}
const [messages, setMessages] = useState<Message[]>([]);Kait useChat
Enkapsulasi koneksi, status pesan, dan fungsi pengiriman dalam satu kait.
function useChat(roomId: string) {
const [messages, setMessages] = useState<Message[]>([]);
useEffect(() => {
socket.connect();
socket.emit('join-room', roomId);
socket.on('message', (msg: Message) => setMessages(m => [...m, msg]));
return () => {
socket.off('message');
socket.emit('leave-room', roomId);
socket.disconnect();
};
}, [roomId]);
const sendMessage = useCallback((text: string) => {
const msg: Message = { id: crypto.randomUUID(), text, sender: 'me', timestamp: Date.now() };
socket.emit('message', msg);
}, []);
return { messages, sendMessage };
}Komponen Daftar Pesan
Render pesan dalam daftar yang dapat digulir. Gunakan useRef pada penanda di bagian bawah, lalu gulir ke penanda tersebut saat pesan baru tiba.
function MessageList({ messages }: { messages: Message[] }) {
const bottomRef = useRef<HTMLDivElement>(null);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
return (
<div className="message-list">
{messages.map(msg => (
<div key={msg.id} className={`msg ${msg.sender === 'me' ? 'mine' : 'theirs'}`}>
<span>{msg.sender}</span>
<p>{msg.text}</p>
</div>
))}
<div ref={bottomRef} />
</div>
);
}Komponen Masukan Pesan
Masukan terkontrol yang memancarkan peristiwa saat menekan Enter atau mengeklik button. Kosongkan masukan setelah mengirim.
function MessageInput({ onSend }: { onSend: (text: string) => void }) {
const [text, setText] = useState('');
const handleSend = () => {
if (!text.trim()) return;
onSend(text.trim());
setText('');
};
return (
<div className="input-row">
<input
value={text}
onChange={e => setText(e.target.value)}
onKeyDown={e => e.key === 'Enter' && handleSend()}
placeholder="Type a message..."
/>
<button onClick={handleSend}>Send</button>
</div>
);
}Merakit UI Obrolan
Gabungkan kait dan subkomponen menjadi komponen ChatRoom.
function ChatRoom({ roomId }: { roomId: string }) {
const { messages, sendMessage } = useChat(roomId);
return (
<div className="chat-room">
<h2>Room: {roomId}</h2>
<MessageList messages={messages} />
<MessageInput onSend={sendMessage} />
</div>
);
}Pembaruan Optimistis
Tambahkan pesan ke status lokal segera sebelum server mengonfirmasinya untuk memberikan umpan balik seketika. Sinkronkan ulang atau hapus pesan tersebut jika server mengembalikan kesalahan.
const sendMessage = useCallback((text: string) => {
const optimistic: Message = { id: crypto.randomUUID(), text, sender: 'me', timestamp: Date.now() };
setMessages(m => [...m, optimistic]); // instant feedback
socket.emit('message', optimistic, (err) => {
if (err) setMessages(m => m.filter(msg => msg.id !== optimistic.id));
});
}, []);Indikator Pengetikan
Pancarkan peristiwa typing saat masukan berubah (dengan penundaan), lalu dengarkan peristiwa pengetikan pengguna lain untuk menampilkan indikator.
const emitTyping = useMemo(() => debounce(() => socket.emit('typing'), 300), []);
useEffect(() => {
socket.on('user-typing', (user) => setTypingUser(user));
return () => socket.off('user-typing');
}, []);Stempel Waktu Pesan
Format stempel waktu dengan Intl.DateTimeFormat agar tampilannya sesuai lokal.
function formatTime(ts: number) {
return new Intl.DateTimeFormat('en', { hour: '2-digit', minute: '2-digit' }).format(ts);
}
<span className="timestamp">{formatTime(msg.timestamp)}</span>Tanda Terima Baca
Pancarkan peristiwa read saat pengguna melihat pesan, lalu dengarkan konfirmasi baca dari server untuk menampilkan tanda centang.
Daftar Pesan Tervirtualisasi
Untuk riwayat obrolan yang panjang, gunakan react-window atau react-virtual untuk memvirtualisasi daftar pesan dan hanya merender baris yang terlihat.
Membatasi Riwayat Pesan
Batasi larik pesan dalam status untuk mencegah pertumbuhan memori yang tidak terbatas selama sesi yang panjang.
socket.on('message', (msg: Message) => {
setMessages(prev => [...prev.slice(-499), msg]); // keep last 500
});Pemeriksaan Singkat
Apa tujuan menggulir ke elemen penanda bagian bawah saat pesan baru tiba dalam daftar obrolan?
Rangkuman
Buat obrolan waktu nyata dengan kait useChat yang mengenkapsulasi logika soket, MessageList dengan gulir otomatis, dan MessageInput yang dikosongkan saat pengiriman. Gunakan pembaruan optimistis untuk umpan balik seketika dan batasi riwayat pesan guna menghindari kebocoran memori.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Membangun Komponen Obrolan Waktu Nyata” gratis?
Ya — teks lengkap “Membangun Komponen Obrolan Waktu Nyata” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus React Academy, upgrade ke CoddyKit PRO. Kursus React Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Membangun Komponen Obrolan Waktu Nyata”?
Tampilkan pesan langsung dalam daftar obrolan yang dapat digulir menggunakan event WebSocket dan status React. Kamu berlatih React Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai React Academy?
Tidak diperlukan pengalaman sebelumnya. React Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Membangun Komponen Obrolan Waktu Nyata” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran React Academy ini?
Ya. Setiap pelajaran React Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Dasar-Dasar WebSocket di Browser
- Menggunakan Socket.IO dengan React
- Membangun Komponen Obrolan Waktu Nyata
- Penyambungan Kembali, Penanganan Kesalahan & Pembersihan