3

I'm learning React, JS and I'm trying to use the .map method to display some data in an array. For each element in the array I create a button to show/hide a description with css and I'm looking for a way to only show the description of one element instead of all descriptions. It is probably unclear but here is the code :

import "./styles.css";
import React, { useState } from "react";

export default function App() {
  const [showDescription, setshowDescription] = useState(false);
  const [anArray] = useState([
    { title: "First Div", description: "First description"},
    { title: "Antoher Div", description: "Another description"}
  ]);
  return (
    <div className="App">
      {anArray.map((val, index) => {
        return (
          <div className="div" key={index}>
            <div className="title">{val.title}</div>
            <button className="btn" onClick={() => setshowDescription(!showDescription)}>
              Show description
            </button>
            <div id={showDescription ? "display" : "hidden"}>
              <div className="description">{val.description}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

Do you have any idea please ?

3
  • 1
    Can you please copy paste the same code here instead of an image. Commented Mar 26, 2021 at 6:59
  • 1
    Please do try to include a Minimal, Complete, and Reproducible Code Example in your question. You'll likely get more help if you make it easier to help. Images aren't as readable nor searchable. Commented Mar 26, 2021 at 7:07
  • 1
    Do you want to display the description of the selected node only? By the way, welcome to SO. One quick tip * t is probably unclear but here is the code * is the approach you want to avoid, it will get you down votes more likely. If you try to make it as clear as you can, it is more likely that you will get the help you want :) Just pointing out Commented Mar 26, 2021 at 7:11

3 Answers 3

3

Issue

You've a single boolean showDescription state that is toggling every description.

Solution

Store an index of the description you want to toggle. Use the index to match the currently mapped element. Conditionally render the description

export default function App() {
  const [showId, setShowId] = useState(null);

  // curried function to toggle to new index or back to null to hide
  const toggleDescription = id => () => setShowId(showId => showId === id ? null : id);

  const [anArray] = useState([
    { title: "First Div", description: "First description"},
    { title: "Antoher Div", description: "Another description"}
  ]);

  return (
    <div className="App">
      {anArray.map((val, index) => {
        return (
          <div className="div" key={index}>
            <div className="title">{val.title}</div>
            <button className="btn" onClick={toggleDescription(index)}> // <-- pass index
              Show description
            </button>
            {showId === index && ( // <-- check for index match
              <div> 
                <div className="description">{val.description}</div>
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

Comments

3

You can use index to show/hide your div. The issue is you are using only one Boolean value to handle it.

export default function App() {
  const [showDescriptionIndex, setshowDescriptionIndex] = useState(-1);
  const [anArray] = useState([
    { title: "First Div", description: "First description"},
    { title: "Antoher Div", description: "Another description"}
  ]);
  return (
    <div className="App">
      {anArray.map((val, index) => {
        return (
          <div className="div" key={index}>
            <div className="title">{val.title}</div>
            <button className="btn" onClick={() => setshowDescriptionIndex(index)}>
              Show description
            </button>
            <div id={showDescriptionIndex === index ? "display" : "hidden"}>
              <div className="description">{val.description}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

Comments

2

Try It

import "./styles.css";
import React, { useState } from "react";

export default function App() {
  const [showDescription, setshowDescription] = useState({});
  const [anArray] = useState([
    { title: "First Div", description: "First description"},
    { title: "Antoher Div", description: "Another description"}
  ]);
  return (
    <div className="App">
      {anArray.map((val, index) => {
        return (
          <div className="div" key={index}>
            <div className="title">{val.title}</div>
            <button className="btn" onClick={() => setshowDescription({...showDescription, [index]: !showDescription[index]})}>
              Show description
            </button>
            <div id={showDescription && showDescription[index] ? "display" : "hidden"}>
              {showDescription[index]}
              <div className="description">{val.description}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
}

Tip: Use class="show/hide" instead of id="show/hide"

Comments

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.