React中点击聊天室按钮如何跨组件触发消息加载并渲染对应内容
实现方案
核心原理
兄弟组件通信采用状态提升方案:将两个组件需要共享的「当前选中的聊天室ID」状态提升到它们的公共父组件中管理,父组件负责向下传递状态和状态更新方法,实现组件间的数据联动。
完整可运行代码示例
1. 公共父组件(示例为App.jsx)
import React from 'react' import ChatRoomList from './ChatRoomList' import ChatMessages from './ChatMessages' export default function App() { // 公共状态:当前选中的聊天室ID,null代表未选中 const [currentChatId, setCurrentChatId] = React.useState(null) return ( <div style={{ display: 'flex', gap: '20px' }}> {/* 把修改选中ID的方法传给聊天室列表组件 */} <ChatRoomList param1="你的业务参数" onChatOpen={setCurrentChatId} /> {/* 把当前选中的ID传给消息展示组件 */} <ChatMessages chatId={currentChatId} /> </div> ) }
2. 修改后的ChatRoomList组件
import React from 'react' import Button from '@mui/material/Button' // 保持你原有MUI按钮的引入逻辑 // 接收父组件传入的onChatOpen回调 export default function ChatRoomList({ param1, onChatOpen }) { const [chatRooms, setChatRooms] = React.useState([]) React.useEffect(() => { (async () => { const x = await getChatRoom(param1) console.log(x) setChatRooms(x) })() }, [param1]) // 补充param1为依赖项,避免参数变化时不重新拉取列表 return ( <div className='chatRoomView'> <ul> {chatRooms.map((chatRoom) => { // key用唯一的chatID,不要用index,避免列表更新出错 return ( <li key={chatRoom.chatIDFromTableChats}> <table> <tr> <td> ChatroomID: {chatRoom.chatIDFromTableChats} <br /> Username: {chatRoom.userNameUser2} </td> <td> <Button variant="contained" // 点击时调用父组件传入的回调,把当前聊天室ID传出去 onClick={() => onChatOpen(chatRoom.chatIDFromTableChats)} > open </Button> </td> </tr> </table> </li> ) })} </ul> </div> ) }
3. 修改后的ChatMessages组件
import React from 'react' // 接收父组件传入的当前选中聊天室ID export default function ChatMessages({ chatId }) { const [messages, setMessages] = React.useState([]) // 监听chatId变化,ID变化时自动加载对应聊天室消息 React.useEffect(() => { // 未选中聊天室时不加载 if (!chatId) return loadMessages(chatId) }, [chatId]) // 依赖chatId,ID变更就重新执行加载逻辑 async function loadMessages(ID) { // 这里替换成你的实际接口请求逻辑 const res = await fetch(`你的消息接口地址/${ID}`) const data = await res.json() setMessages(data) } // 未选中聊天室时显示默认提示,选中后显示消息列表 return ( <div className='mainChatView'> {!chatId ? ( 'HI MOM' ) : ( <div> {messages.map((msg, index) => ( <div key={index}>{msg.content}</div> ))} </div> )} </div> ) }
补充说明
如果后续你的组件层级变深,多层传参过于繁琐,可以考虑用Context API或者轻量状态管理库实现通信,当前场景下状态提升是最简单的实现方案。
内容的提问来源于stack exchange,提问作者innom
相关产品推荐
相关产品推荐

