การสร้างคอมโพเนนต์แชตแบบเรียลไทม์
แสดงข้อความสดในรายการแชตที่เลื่อนได้ โดยใช้อีเวนต์ WebSocket และสถานะ React
การสร้างคอมโพเนนต์แชตแบบเรียลไทม์ เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน
สถาปัตยกรรมคอมโพเนนต์แชต
แชตแบบเรียลไทม์มีสามส่วน ได้แก่ รายการข้อความ (แสดงผล) ช่องป้อนข้อความ (ส่ง) และชั้นการเชื่อมต่อ WebSocket/Socket.IO ควรเก็บตรรกะซ็อกเก็ตไว้ในฮุกกำหนดเอง
โครงสร้างข้อมูลข้อความ
กำหนดอินเทอร์เฟซ TypeScript สำหรับข้อความแชต เพื่อให้ชนิดข้อมูลของคอมโพเนนต์ปลอดภัยตลอดการทำงาน
interface Message {
id: string;
text: string;
sender: string;
timestamp: number;
}
const [messages, setMessages] = useState<Message[]>([]);ฮุก useChat
ห่อหุ้มการเชื่อมต่อ สถานะข้อความ และฟังก์ชันส่งไว้ในฮุกเดียว
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 };
}คอมโพเนนต์รายการข้อความ
แสดงข้อความในรายการที่เลื่อนได้ ใช้ useRef กับจุดสัญญาณด้านล่าง แล้วเลื่อนไปยังจุดนั้นเมื่อมีข้อความใหม่เข้ามา
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>
);
}คอมโพเนนต์ช่องป้อนข้อความ
ช่องป้อนข้อมูลแบบควบคุมที่ส่งข้อมูลเมื่อกด Enter หรือคลิกปุ่ม ล้างช่องป้อนข้อมูลหลังจากส่ง
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>
);
}การประกอบส่วนติดต่อผู้ใช้แชต
ประกอบฮุกและคอมโพเนนต์ย่อยให้เป็นคอมโพเนนต์ 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>
);
}การอัปเดตแบบมองโลกในแง่ดี
เพิ่มข้อความลงในสถานะภายในเครื่องทันที ก่อนที่เซิร์ฟเวอร์จะยืนยัน เพื่อให้ผู้ใช้ได้รับการตอบสนองทันที หากเซิร์ฟเวอร์ส่งข้อผิดพลาดกลับมา ให้ปรับข้อมูลให้ตรงกันหรือลบข้อความนั้นออก
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));
});
}, []);ตัวบ่งชี้การพิมพ์
ส่งเหตุการณ์ typing เมื่ออินพุตเปลี่ยนแปลง (โดยหน่วงเวลา) และรับฟังเหตุการณ์การพิมพ์ของผู้อื่นเพื่อแสดงตัวบ่งชี้
const emitTyping = useMemo(() => debounce(() => socket.emit('typing'), 300), []);
useEffect(() => {
socket.on('user-typing', (user) => setTypingUser(user));
return () => socket.off('user-typing');
}, []);การประทับเวลาข้อความ
จัดรูปแบบการประทับเวลาด้วย Intl.DateTimeFormat เพื่อให้แสดงผลตามท้องถิ่น
function formatTime(ts: number) {
return new Intl.DateTimeFormat('en', { hour: '2-digit', minute: '2-digit' }).format(ts);
}
<span className="timestamp">{formatTime(msg.timestamp)}</span>การยืนยันการอ่าน
ส่งเหตุการณ์ read เมื่อผู้ใช้ดูข้อความ และรับฟังการยืนยันการอ่านจากเซิร์ฟเวอร์เพื่อแสดงเครื่องหมายถูก
รายการข้อความแบบเสมือน
สำหรับประวัติแชตที่ยาว ให้ใช้ react-window หรือ react-virtual เพื่อทำให้รายการข้อความเป็นเสมือนและแสดงผลเฉพาะแถวที่มองเห็น
การจำกัดประวัติข้อความ
จำกัดจำนวนสมาชิกในอาร์เรย์ข้อความของสถานะ เพื่อป้องกันการใช้หน่วยความจำเพิ่มขึ้นอย่างไม่มีขอบเขตในเซสชันที่ยาวนาน
socket.on('message', (msg: Message) => {
setMessages(prev => [...prev.slice(-499), msg]); // keep last 500
});ตรวจสอบอย่างรวดเร็ว
จุดประสงค์ของการเลื่อนไปยังองค์ประกอบจุดสัญญาณด้านล่างเมื่อมีข้อความใหม่เข้ามาในรายการแชตคืออะไร
สรุปทบทวน
สร้างแชตแบบเรียลไทม์ด้วยฮุก useChat ที่ห่อหุ้มตรรกะซ็อกเก็ต รายการ MessageList ที่เลื่อนลงอัตโนมัติ และ MessageInput ที่ล้างช่องป้อนข้อมูลเมื่อส่ง ใช้การอัปเดตแบบมองโลกในแง่ดีเพื่อให้ตอบสนองทันที และจำกัดประวัติข้อความเพื่อหลีกเลี่ยงหน่วยความจำรั่ว
คำถามที่พบบ่อย
บทเรียน “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์”
แสดงข้อความสดในรายการแชตที่เลื่อนได้ โดยใช้อีเวนต์ WebSocket และสถานะ React คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การสร้างคอมโพเนนต์แชตแบบเรียลไทม์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม
ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน WebSocket ในเบราว์เซอร์
- การใช้ Socket.IO กับ React
- การสร้างคอมโพเนนต์แชตแบบเรียลไทม์
- การเชื่อมต่อใหม่ การจัดการข้อผิดพลาด และการล้างข้อมูล