maxheezy's
maxheezy's

Reputation: 49

Use filter to only show the corresponding data in react

When the user clicks on a list item, I want it to render the paragraph content for that list item. When the user clicks on another list item, I then want to erase the previous content and register then new paragraph data for the new list item. Currently, when I click the list items, the info data stays for all and never goes away. Does this make sense? If you go to this website https://brittanychiang.com/ and click the "experience" button in the nav, you can see the functionality I am going for.

Questions :

import SingleQuestion from "./SingleQuestion";
import classes from "./Question.module.css";

const questions = [
  {
    id: 1,
    title: "Step 1",
    info: "paragraph 1 text",
  },
  {
    id: 2,
    title: "Step 2",
    info: "paragraph 2 text",
  },
  {
    id: 3,
    title: "Step 3",
    info: "paragraph 3 text",
  },
  {
    id: 4,
    title: "Step 4",
    info: "paragraph 4 text",
  },
];

const Questions = () => {
  return (
    <main>
      <h1 className="infoTitle">We have answers</h1>
      <div className={classes.container}>
        {questions.map((question) => {
          return <SingleQuestion key={question.id} {...question} />;
        })}
      </div>
    </main>
  );
};
export default Questions;

SingleQuestion:

import React, { useState } from "react";

import classes from "./Question.module.css";

const SingleQuestion = ({ title, info }) => {
  const [text, setText] = useState("");

  const showTextHandler = () => {
    setText(info);
  };

  return (
    <section className={classes.elementBin}>
      <ul>
        <li className={classes.hi} onClick={showTextHandler}>
          {title}
        </li>
      </ul>
      <p>{text}</p>
    </section>
  );
};

export default SingleQuestion;

Upvotes: 0

Views: 41

Answers (1)

maxpsz
maxpsz

Reputation: 604

There are plenty of ways of solving this, I will just show an example that does not differ so much from your current code:

const Questions = () => {
  const [selectedId, setSelectedId] = useState();

  return (
    <main>
      <h1 className="infoTitle">We have answers</h1>
      <div className={classes.container}>
        {questions.map((question) => {
          return (
            <SingleQuestion
              key={question.id}
              isSelected={question.id === selectedId}
              setSelectedId={setSelectedId}
              {...question}
            />
          );
        })}
      </div>
    </main>
  );
};

const SingleQuestion = ({ id, title, info, isSelected, setSelectedId }) => {
  return (
    <section className={classes.elementBin}>
      <ul>
        <li className={classes.hi} onClick={() => setSelectedId(id)}>{title}</li>
      </ul>
      {isSelected && <p>{info}</p>}
    </section>
  );
};

As you can see, an upper state was created, holding the selected question id.

The setter for that state is passed to the SingleQuestion component.

Now that component does not hold an internal state anymore, it just update the selected question id, and shows its info just if is the selected one.

Upvotes: 1

Related Questions