能否将React.createElement生成的元素追加到现有div?[Object Object]报错求助
问题原因
React.createElement() 返回的是 React虚拟DOM对象,不是浏览器可识别的真实DOM节点。直接调用原生DOM的append()方法添加该对象时,JS会自动调用对象的toString()方法,最终就输出了[Object Object]。
解决方案
方案1:遵循React开发规范(推荐)
如果你的项目整体基于React开发,不要混用原生DOM操作,改用React状态管理消息列表:
- 在组件内定义状态存储消息列表:
const [messageList, setMessageList] = useState([])
- 收到新消息时直接更新状态,不要操作DOM:
socket.on("chat-message", data => { setMessageList(prev => [...prev, data]) })
- 在组件的渲染返回值中遍历
messageList,直接渲染对应的消息节点即可。
方案2:手动渲染React元素为真实DOM(仅适合混合开发临时兼容场景)
如果必须要手动把生成的React元素插入原生DOM容器,需要先把React元素渲染为真实DOM再追加:
React 18+ 版本写法:
import { createRoot } from 'react-dom/client'; socket.on("chat-message", data => { const newMessage = React.createElement('div', {className: "messages"}, [ React.createElement('div', {className: "usernamepic"}, [ React.createElement('img', {src: data.pic, className: "usernamepicsrc"}, null), ]), React.createElement('div', {className: "actualmessages"}, [ React.createElement('div', {className: "authorname"}, data.name), React.createElement('div', {className: "messagetext"}, data.message), ]), ]) const messageContainer = document.getElementById("actualchatmessages"); // 新建临时容器挂载React元素 const tempWrapper = document.createElement('div'); const root = createRoot(tempWrapper); root.render(newMessage); // 追加渲染后的真实DOM到目标容器 messageContainer.append(tempWrapper.firstChild); })
React 17及更早版本写法:
import ReactDOM from 'react-dom'; socket.on("chat-message", data => { const newMessage = React.createElement('div', {className: "messages"}, [ React.createElement('div', {className: "usernamepic"}, [ React.createElement('img', {src: data.pic, className: "usernamepicsrc"}, null), ]), React.createElement('div', {className: "actualmessages"}, [ React.createElement('div', {className: "authorname"}, data.name), React.createElement('div', {className: "messagetext"}, data.message), ]), ]) const messageContainer = document.getElementById("actualchatmessages"); const tempWrapper = document.createElement('div'); ReactDOM.render(newMessage, tempWrapper); messageContainer.append(tempWrapper.firstChild); })
内容的提问来源于stack exchange,提问作者MultiThunderXXL
相关产品推荐
相关产品推荐

