You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React开发WhatsApp克隆:无法遍历messages,props未定义

React WhatsApp克隆应用:Chat组件messages props undefined无法渲染消息列表

你遇到的核心问题是状态更新语法错误+未处理空/undefined状态导致的渲染失败,以下是具体问题分析和修复方案:


问题1:Pusher回调中状态更新语法错误

App.js里Pusher的insert回调中,setMessages(...messages, newMessage)写法错误。setMessages需要接收完整的新数组,而不是把数组元素拆成单独参数。正确做法是用函数式更新,依赖之前的状态生成新数组,还能避免闭包导致的状态不一致:

// 错误写法
setMessages(...messages, newMessage);
// 正确写法
setMessages(prevMessages => [...prevMessages, newMessage]);

问题2:Chat组件未处理messages可能为undefined的情况

虽然App组件初始将messages设为空数组,但如果异步请求未完成、或父组件状态更新延迟时,直接调用messages.map会报错。需要添加可选链判断或条件渲染:

// 用可选链处理
{messages?.map((message) => (...))}
// 或条件判断
{messages && messages.map((message) => (...))}

问题3:axios请求缺少错误处理

原代码中axios.get的catch块为空,无法排查请求是否失败,建议添加错误日志:

.catch(err => {
  console.error("获取消息失败:", err);
});

修改后的完整代码

App.js

import './App.css';
import Sidebar from './components/sidebar/Sidebar';
import Chat from './components/chat/chat';
import Pusher from 'pusher-js';
import { useEffect, useState } from 'react';
import axios from './axios';

function App() {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    axios.get("/messages/sync")
      .then((response) => {
        setMessages(response.data)
      })
      .catch(err => {
        console.error("获取消息失败:", err);
      });
  }, []);

  useEffect(() => {
    const pusher = new Pusher('a2e1d7e0112669256b0c', {
      cluster: 'eu'
    });

    const channel = pusher.subscribe('messages');
    channel.bind('insert', function (newMessage) {
      setMessages(prevMessages => [...prevMessages, newMessage]);
    });

    return () => {
      channel.unbind_all();
      channel.unsubscribe();
    }
  }, []); // 用函数式更新后无需依赖messages

  return (
    <div className="app">
      <div className='appBody'>
        <Sidebar></Sidebar>
        <Chat messages={messages}></Chat>
      </div>
    </div>
  );
}

export default App;

Chat组件

const Chat = ({messages}) => {
    return (
        <div className='chat'>
            <div className='chat_header'>
                <Avatar></Avatar>
                <div className='chat_header_info'>
                    <h3>Chat Name</h3>
                    <p><strong>Last seen: </strong>2 hours ago</p>
                </div>
                <div className='chat_header_right'>
                    <IconButton>
                        <SearchOutlined></SearchOutlined>
                    </IconButton>
                    <IconButton>
                        <AttachFile></AttachFile>
                    </IconButton>
                    <IconButton>
                        <MoreVert></MoreVert>
                    </IconButton>
                </div>
            </div>
            <div className='chat_body'>
                {messages?.map((message, index) => (
                    <p key={index} className='chat_message'>
                        <span className='chat_name'>{message.name}</span>
                        {message.message}
                        <span className='chat_timestamp'>{message.timestamp}</span>
                    </p>
                ))}
                <p className='chat_message chat_receiver'>
                    <span className='chat_name'>Mio nome</span>
                    messaggio
                    <span className='chat_timestamp'>{new Date().toUTCString()}</span>
                </p>
            </div>
            <div className='chat_footer'>
                <IconButton>
                    <InsertEmoticon></InsertEmoticon>
                </IconButton>
                <form>
                    <input placeholder='Scrivi un messaggio...' type="text"></input>
                    <button type='submit'></button>
                </form>
            </div>
        </div>
    );
}
export default Chat;

内容的提问来源于stack exchange,提问作者Christian Termo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:05:18