Home > Blockchain >  I can not handle clicking a specific element inside the map loop
I can not handle clicking a specific element inside the map loop

Time:10-09

I want when I click on a button, only the message above it will be shown, not all the messages. And note that I dont want to have multiple useState for each messages.

The following example is very similar to my code:

  import { useState } from "react";
  import { messages } from "./messagesData";

  export default App() {

  const [ isShowingMessage, setIsShowingMessage ] = useState(false);

  function showMessage() {
    setIsShowingMessage(true)
  }

  const renderedMessages = messages.map(message => (
    <div>
      <div className={!isShowingMessage ? "d-none" : "d-block"}>
        {message.title}
      </div>
      <button onClick={showMessage}> 
        the button which only show {message.title} message {/* title can be First, Second and 
        Third */}
      </button>
    </div>
  ))
  return (
    <div>
      {renderedMessages}
    </div>
  )
}

any help would be appreciated

CodePudding user response:

Your every message should have a unique id. When the user clicks a button you have to pass the id of the message as a parameter of the clickHandler function and in the click handler function you have to store the id in a state and then the condition will be like clickedId === message.id? "d-block" : "d-none"

If there is a unique id for every message then it should work fine

import { messages } from "./messagesData";
import { useState } from "react";
export default function App() {
  const [clickedId, setClickedId] = useState(null);
  const handleClick = (id) => {
    setClickedId(id);
  };
  const renderedMessages = messages.map((message) => (
    <div>
      <div style={{ display: clickedId === message.id ? "block" : "none" }}>
        {message.title}
      </div>
      <button onClick={() => handleClick(message.id)}>
        the button which only show {message.title} message{" "}
        {/* title can be First, Second and 
        Third */}
      </button>
    </div>
  ));
  return <div>{renderedMessages}</div>;
}

CodePudding user response:

Create new component for displaying message

import { useState } from "react";
  import { messages } from "./messagesData";

  function MessageComponent({message}) {
  
  const [ isShowingMessage, setIsShowingMessage ] = useState(false);

  function showMessage() {
    setIsShowingMessage(true)
  }

   return (
       <div>
      <div className={!isShowingMessage ? "d-none" : "d-block"}>
        {message.title}
      </div>
      <button onClick={showMessage}> 
        the button which only show {message.title} message {/* title can be First, Second and 
        Third */}
      </button>
    </div>
   )
  }

  export default App() {

  const renderedMessages = messages.map(message => (
   <MessageComponent message={message} key={message} />
  ))
  return (
    <div>
      {renderedButton}
    </div>
  )
}
  • Related