原生JS追加DOM代码转React实现遇阻,求解决方案
Let's break down what's going wrong with your current React code and get it working just like your original vanilla JS implementation!
What's Off in Your Current Code
- Wrong state type for messages: You're setting
incomemsgsto a single object{ text }, but you need an array to store multiple messages (since you're appending new ones over time). - Incorrect state update: When adding a new message, you're replacing the entire
incomemsgsinstead of appending to it. React state updates should preserve existing data unless you intend to overwrite it. - Incomplete rendering: Your map function returns an empty
<div>instead of recreating the full message UI structure from your vanilla code.
Step-by-Step Solution
1. Fix Your Initial State
Make sure incomemsgs starts as an empty array (not an object):
state = { remoteStreams: [], Message:'', incomemsgs: [], // Empty array for storing messages };
2. Correctly Append New Messages
Use React's functional setState to safely add new messages to the array. We'll also include the formatted time just like your original code:
// First, make sure you have the formatAMPM function available in your component formatAMPM = (date) => { let hours = date.getHours(); let minutes = date.getMinutes(); let ampm = hours >= 12 ? 'pm' : 'am'; hours = hours % 12; hours = hours ? hours : 12; // Convert 0 hour to 12 minutes = minutes < 10 ? '0'+minutes : minutes; return `${hours}:${minutes} ${ampm}`; } // When you need to add a new message: addNewMessage = (text) => { const currentTime = this.formatAMPM(new Date()); // Use functional setState to get the latest state safely this.setState(prevState => ({ incomemsgs: [...prevState.incomemsgs, { text, time: currentTime }] })); }
Note: Using the spread operator ([...prevState.incomemsgs]) creates a new array instead of mutating the old one, which is best practice in React to ensure proper re-renders.
3. Render the Messages Properly
Now map over the incomemsgs array and render the full message structure matching your vanilla JS code:
// Inside your component's render method render() { const { incomemsgs } = this.state; return ( <div className="msg_card_body"> {incomemsgs.map((msg, index) => ( <div key={index} className="d-flex justify-content-start"> <div className="msg_cotainer"> <div className="msg_time"> You <span>{msg.time}</span> </div> <div>{msg.text}</div> </div> </div> ))} </div> ); }
For better reliability, if you have unique IDs for each message (like a timestamp or backend ID), use that instead of index as the key prop.
Key Takeaways
- Always use arrays for collections of items (like messages) in React state.
- Use functional
setStatewhen updating state based on previous state values to avoid race conditions. - Never mutate state directly (always return new arrays/objects).
- Replicate the full UI structure from your original code to keep the message display consistent.
内容的提问来源于stack exchange,提问作者unique

