1

I didn't know how to ask this but basically I just want list of buttons that display different text. When you click a button it shows the text. But instead of hardcoding every button I want it to be dynamic. So far when I click any of my buttons, everything shows instead of individually. (one button should show one definition" I think it is the way I am using state probably.

import React, { useState } from "react";
import terms from "./TermsComponentData.js";
import "./TermsComponent.css";
function TermsComponent() {
  const [showTerm, setShowTerm] = useState(false);
  const buttonList = terms.map((term, index) => (
    <div>
      {showTerm && <h1>{term.definition}</h1>}
      <button
        key={index}
        className="buttons-container-button"
        onClick={() => {
          setShowTerm(!showTerm);
        }}
      >
        {term.name}
      </button>
    </div>
  ));

  return (
    <div className="terms-container">
      <div className="buttons-container">{buttonList}</div>
    </div>
  );
}

MY DATA

const terms = [
  {
   
    name: "Term1",
    definition: "This is the definition1",
  },
  {
   
    name: "Term2",
    definition: "This is the definition2",
  },
  {
   
    name: "Term3",
    definition: "This is the definition 3",
  },
  {
   
    name: "Term4",
    definition: "This is the definition 4",
  }
];

export default terms;

1 Answer 1

1

Currently your state variable showTerm is common for all of the buttons. So to achieve the result you are describing, you need to encapsulate the state for each button.

The easiest way to do this, is to create a separate component which contains the showTerm state, and then map a list of this component with the given data based on the terms:

// 👇 added separate term button with it's own state
function TermButton({ term }) {
  const [showTerm, setShowTerm] = useState(false);

  return (
    <div>
      {showTerm && <h1>{term.definition}</h1>}
      <button
        className="buttons-container-button"
        onClick={() => {
          setShowTerm(!showTerm);
        }}
      >
        {term.name}
      </button>
    </div>
  );
}

function TermsComponent() {
  return (
    <div className="terms-container">
      <div className="buttons-container">
        { // 👇 for each term, create a TermButton with the given term
          terms.map((term, index) => <TermButton key={index} term={term} />)}
       </div>
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

5 Comments

Worked like a charm! You da bomb! For those following, I had to pass index property in the Termbutton function. So ....function TermButton ({term , index})......instead of function TermButton ({term}). It was so obvious just create a separate component! love it.
I've updated the example, so the key is set for the TermsButton directly & removed index from button inside the component.
Thank you! If I wanted to make the output of all buttons show text in one place do I need If statements? or cases? For example I hit button 1 it shows text, I hit button 2 it replaces that same text.
@lache Let me know if you figure out how to output the text in one place. Here the working link for your code so far : codesandbox.io/s/bold-haze-xpzrv?file=/src/TermsComponent.js
I have a newer version but I have not used codesandbox.io, how do I add it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.