Home > OS >  React append child after parent already rendered
React append child after parent already rendered

Time:02-27

I am working on a messaging app. I have a useState which is called 'messages' and it renders the messages from a certain chat on the screen. For now, every time a user sends a message, it is added to the messages useState but I want it to just be appended to the messages <div>. How can I append a message to the existing messages without changing the useState?

My main chat code looks somethings like this:

import React, { useState } from 'react'; 

export default function Main() {
    const [messages, setMessages] = useState([]);
    const [message, setMessage] = useState('');
    
    // Message Managment
    function chatInputPressed(e) {
        if ((e.key === 'Enter' || e.keyCode === 13) && message !== '') { // Check if the user pressed the Enter key
            setMessages(oldMsgs => ([message, ...oldMsgs])); // Insert the new message to the messages useState
            setMessage(''); // Set the message to empty
            
        }
    }

    return (
        <div className='Main'>
            <div className='messages'>
                {messages.map(m => (
                    <div key='random-key' className='message' >{m}</div>
                ))}
            </div>
            <input 
                type="text" 
                id="message-input" 
                value={ message } 
                onChange={ (e) => setMessage(e.target.value) } 
                onKeyDown={ chatInputPressed } 
            >
            </input>
        </div>

    );
}

I want to append a new message <div> element to <div className='messages'> instead of updating the messages like this setMessages(oldMsgs => ([message, ...oldMsgs]));.

CodePudding user response:

You can handle it like below.

  1. You can keep a refs array to refer later to each message div element. Then use the index or messageId (create a unique one) to update the styles.
const [messageRefs, setMessageRefs] = useState([]);
  1. create and add a new ref for each message submission.
  // Message Managment
  function chatInputPressed(e) {
    if ((e.key === "Enter" || e.keyCode === 13) && message !== "") {
      // Check if the user pressed the Enter key
      setMessageRefs((prev) => [createRef(null), ...prev]);
      setMessages((oldMsgs) => [message, ...oldMsgs]); // Insert the new message to the messages useState
      setMessage(""); // Set the message to empty
    }
  }
  1. For example if you wanted to change the color of a single message define a handler like below. In your case, it will be a callback for the API call to the backend.
  function styleMessage(index) {
    const mssageRef = messageRefs[index]?.current;
    mssageRef.style.color = "red";
  }

For example, I have added this as a click handler to each message to alter the color.

Edit modest-cray-r6y3y6

  • Related