Search code examples
javascriptreactjsreact-hookssetstate

Dynamically render data and render components conditionally: React JS


I am trying to implement a details page where I am displaying details corresponding to each items. Each item will have its own details which will be shown on "Show Details" and details of corresponding item should be hidden when "Hide Details" is clicked. There are two components Item and ItemDetailViewer that shows individual items and its details correspondingly. I am unable to implement the Show/Hide for each Item component.

Also on click of show details of each item the details should be displayed in a table. The items for this table are different for different items ; this should be populated dynamically.

Can someone help me here?

Code sandbox: https://codesandbox.io/s/summer-surf-4h0g6

App Component

import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import ItemViewer from "./Item";

const item1 = ["i1d1", "i2d2", "i3d3"];
const item2 = ["i2d1", "i2d2", "i2d3"];
const item3 = ["i3d1", "i3d2", "i3d3"];

const item1Detail = [
  { age: 21, email: "[email protected]" },
  { age: 19, email: "[email protected]" }
];
const item2Detail = [
  { id: 24, phone: "454654654644" },
  { id: 29, phone: "465654654643" }
];
const item3Detail = [
  { index: 25, address: "dsdsdsdsds" },
  { index: 39, address: "trytytytyy" }
];
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      item1: [],
      item2: [],
      item3: [],
      item1Detail: [],
      item2Detail: [],
      item3Detail: []
    };
  }

  componentDidMount() {
    this.setState({
      item1,
      item2,
      item3,
      item1Detail,
      item2Detail,
      item3Detail
    });
  }

  render() {
    let {
      item1,
      item2,
      item3,
      item1Detail,
      item2Detail,
      item3Detail
    } = this.state;
    return (
      <>
        <ItemViewer
          index="1"
          item="item1"
          itemData={item1}
          itemDetailData={item1Detail}
        />
        <ItemViewer
          index="2"
          item="item2"
          itemData={item2}
          itemDetailData={item2Detail}
        />
        <ItemViewer
          index="3"
          item="item3"
          itemData={item3}
          itemDetailData={item3Detail}
        />
      </>
    );
  }
}



ItemViewer Component

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

const ItemViewer = props => {
  const [isitem1, setItem1] = useState(false);
  const [isitem2, setItem2] = useState(false);
  const [isitem3, setItem3] = useState(false);
  const [openDetails, setOpenDetails] = useState(false);
  function renderItems(list, itemType, itemDetailData) {
    if (list && list.length > 0) {
      return (
        <>
          <ul>
            {list.map(function(item) {
              return <li key={item}>{item}</li>;
            })}
          </ul>
          {!openDetails && (
            <button onClick={() => handleClick(itemType)}>View Details</button>
          )}
          {openDetails && (
            <button onClick={() => handleClick(itemType)}>Hide Details</button>
          )}
          {isitem1 && (
            <ItemDetailViewer showDetais={openDetails} data={itemDetailData} />
          )}
          {isitem2 && (
            <ItemDetailViewer showDetais={openDetails} data={itemDetailData} />
          )}
          {isitem3 && (
            <ItemDetailViewer showDetais={openDetails} data={itemDetailData} />
          )}
        </>
      );
    } else {
      return <p>No Items Found</p>;
    }
  }
  function handleClick(item) {
    if (item === "item1") {
      setItem1(true);
      setOpenDetails(!openDetails);
    }
    if (item === "item2") {
      setItem2(true);
      setOpenDetails(!openDetails);
    }
    if (item === "item3") {
      setItem3(true);
      setOpenDetails(!openDetails);
    }
  }
  return (
    <div>
      <span>
        {props.index}: {props.item}
      </span>
      <div>{renderItems(props.itemData, props.item, props.itemDetailData)}</div>
    </div>
  );
};

export default ItemViewer;


ItemDetail Component

import React from "react";

const ItemDetailViewer = props => {
  return (
    <>
      {
        <table>
          <tbody>
            <tr>
              <th>Key corresponding to each item</th>
              <td>Value corresponding to each item</td>
            </tr>
          </tbody>
        </table>
      }
    </>
  );
};
export default ItemDetailViewer;


Solution

  • Check out this updated sandbox https://codesandbox.io/s/sad-wildflower-ek8ed