skip to Main Content

On click on child level plus icon, how can we match tagname from two state variables and display the data of the clicked item only in react page. Right now I am filtering
data based on id, but the data in displayed multiple time as per screen shot. Could someone please advise here on how can i resolve it ?

CSB link added
https://codesandbox.io/s/epic-lake-g3s2q6?file=/src/App.js:0-3032

import React, { useState, useEffect, useCallback } from "react";

const data = [
  {
    id: 1,
    count: 10,
    tagname: "react"
  },
  {
    id: 2,
    count: 3,
    tagname: "unix"
  },
  {
    id: 3,
    count: 5,
    tagname: "cypress"
  }
];

const detailsTag = [
  {
    id: 1,
    tagname: "react",
    blogdetails: "React State "
  },
  {
    id: 2,
    tagname: "unix",
    blogdetails: "Unix commands"
  },
  {
    id: 3,
    tagname: "cypress",
    blogdetails: "Cypress request command"
  }
];

const GroupByTags = () => {
  const [groupTags, setGroupTags] = useState(data);
  const [detailsTags, setDetailsTags] = useState(detailsTag);
  const [filterTags, setFilterTags] = useState([]);
  const [isShown, setIsShown] = useState(false);
  const [isShownFullDetails, setShowFullDetails] = useState(false);

  const style = {
    width: "30px",
    height: "30px",
    marginLeft: "20px",
    backgroundColor: "#dae0f5",
    fontWeight: "900",
    opacity: 1,
    borderColor: "#fafcff"
  };

  const handleClick = (event) => {
    setIsShown((current) => !current);
  };

  const showFullDetails = (idx) => {
    const filterdata = detailsTags.filter((item) => item?.id === idx);
    setShowFullDetails((current) => !current);
    setFilterTags(filterdata);
  };

  return (
    <div id="App">
      <div className="groupbyTags">
        <div className="row">
          <div className="plusBtn">
            <input
              onClick={handleClick}
              style={style}
              type="button"
              value="+"
            ></input>
          </div>
          {isShown && (
            <div className="groupByTagData">
              {groupTags.map(({ id, count, tagname }) => (
                <div key={id} className="row">
                  <div className="groupByTagInfo">
                    <input
                      onClick={() => showFullDetails(id)}
                      style={style}
                      type="button"
                      value="+"
                    ></input>
                  </div>{" "}
                  <br></br>
                  {isShownFullDetails && (
                    <div className="groupByTagData">
                      {filterTags.map(({ id, tagname, blogdetails }) => (
                        <div key={id} className="row">
                          <div className="groupByTagDetails">
                            <div className="groupByTagName">{blogdetails}</div>
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                  <div className="groupByTagInfo">
                    <span className="groupByTagCount">{count}</span>
                  </div>
                  <div className="groupByTagInfo">
                    <span className="groupByTagName">{tagname}</span>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default GroupByTags;

Issue here React State is displayed multiple time.

enter image description here

2

Answers


  1. First of all you should change the way you map the array:

    {isShown && (
                <div className="groupByTagData">
                  {groupTags.map((e) => (
                    <div key={e.id} className="row">
                      <div className="groupByTagInfo">
                        <input
                          onClick={() => showFullDetails(e.id)}
                          style={style}
                          type="button"
                          value="+"
                        ></input>
                      </div>{" "}
                      <br></br>
                      {isShownFullDetails && (
                        <div className="groupByTagData">
                          {filterTags.map((j) => (
                            <div key={j.id} className="row">
                              <div className="groupByTagDetails">
                                <div className="groupByTagName">{j.blogdetails}</div>
                              </div>
                            </div>
                          ))}
                        </div>
                      )}
                      <div className="groupByTagInfo">
                        <span className="groupByTagCount">{e.count}</span>
                      </div>
                      <div className="groupByTagInfo">
                        <span className="groupByTagName">{e.tagname}</span>
                      </div>
                    </div>
                  ))}
                </div>
              )}
    
    

    Try this way of mapping

    Login or Signup to reply.
  2. Can you try this

    const showFullDetails = (idx) => {
        const filterdata = detailsTags.filter((item) => item?.id === idx);
        setShowFullDetails((prev) => (prev === idx ? false : idx));
        setFilterTags(filterdata);
    };
    ....
    {
        isShownFullDetails === id && (
            <div className="groupByTagData">
                {filterTags.map(({ id, tagname, blogdetails }) => (
                    <div key={id} className="row">
                        <div className="groupByTagDetails">
                            <div className="groupByTagName">{blogdetails}</div>
                        </div>
                    </div>
                ))}
            </div>
        );
    }
    

    codesandbox

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search