1
\$\begingroup\$

I am working on a project in react. Where most of the data on different tabs have a table. So I design the "TableItems" component and passed the data according to the component. Right now based on params I toggle the table data. Is this the correct way? some tables have different columns so the data table is varying.

import React, { useState } from "react";
import { DoctorData, PatientData } from "./data";
import "./styles.css";
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Link,
  useLocation
} from "react-router-dom";

export const Doctor = () => {
  const header = ["ID#", "Name", "Disease", "Doctor", "Contact"];
  return (
    <div className="split">
      <Link to="/patient">Paitent</Link>
      <TableItems header={header} rowData={DoctorData} />
    </div>
  );
};

export const Patient = () => {
  const header = ["ID#", "Name", "Specialization", "Email", "Contact"];
  return (
    <div className="split">
      <Link to="/">Doctor</Link>
      <TableItems header={header} rowData={PatientData} />
    </div>
  );
};

export const TableItems = ({ header, rowData }) => {
  const location = useLocation();
  return (
    <div className="doctors-list">
      <table>
        <thead>
          <tr>
            <th className="checkbox-rect">
              <input type="checkbox" id="checkbox-rect1" name="check" />
              <label htmlFor="checkbox-rect1">
                <span></span>
              </label>
            </th>
            {header.map((data, index) => (
              <th key={index}>{data}</th>
            ))}
            <th></th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {location.pathname == "/" &&
            rowData &&
            rowData.map((data, index) => (
              <tr key={index}>
                <td className="checkbox-rect">
                  <input type="checkbox" id="checkbox-rect1" name="check" />
                  <label htmlFor="checkbox-rect1">
                    <span></span>
                  </label>
                </td>
                <td>{data.id}</td>
                <td>{data.name}</td>
                <td>{data.specs}</td>
                <td>{data.email}</td>
                <td>{data.contact}</td>
                <td>
                  <i className="fa-solid fa-pen"></i>
                </td>
                <td>
                  <i className="fa-solid fa-trash-can"></i>
                </td>
              </tr>
            ))}

          {location.pathname == "/patient" &&
            rowData &&
            rowData.map((data, index) => (
              <tr key={index}>
                <td className="checkbox-rect">
                  <input type="checkbox" id="checkbox-rect1" name="check" />
                  <label htmlFor="checkbox-rect1">
                    <span></span>
                  </label>
                </td>
                <td>{data.id}</td>
                <td>{data.name}</td>
                <td>{data.disease}</td>
                <td>{data.doctor}</td>
                <td>{data.contact}</td>
                <td>
                  <i className="fa-solid fa-pen"></i>
                </td>
                <td>
                  <i className="fa-solid fa-trash-can"></i>
                </td>
              </tr>
            ))}
        </tbody>
      </table>
    </div>
  );
};

////// MAIN APP LAYOUT
export default function App() {
  return (
    <>
      <Router>
        <Routes>
          <Route path="/" element={<Doctor />} />
          <Route path="/patient" element={<Patient />} />
        </Routes>
      </Router>
    </>
  );
}
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Big Red Exclamation Mark !

This is definitely not how you would design a generic component.

The TableItems component should not know anything about the current url, and it should not know the structure of the row data. Or in other words, the structure for row data must be the same no matter what kind of data the table ought to display.

I am not fronend developer and I don't work with react so I won't give you any react code. But I have enough understanding to claim that your approach is 100% wrong. I can tell you, however, how to make it generic regardless if this is react or even frontend code.

It's actually pretty simple. Just as I said, pass the same data type for both doctor and patient components. The data type could be string[]. Alternatively, instead of converting the data before passing it to the component, you can pass the original data, but also pass a function that would convert them to the common structure upon rendering.

// pass doctorTableRows to TableItems component
const doctorTableRows = doctorData.map((doctor) => [doctor.id, doctor.name, doctor.specs, doctor.email, doctor.contact])


// pass patientTableRows to TableItems component
const patientTableRows = patientData.map((patient) => [patient.id, patient.name, patient.disease, patient.doctor, patient.contact])

Also the class name of the top level div is weird - doctor-list - again if this is supposed to be a generic table component, it must not know such specific things like classes from the doctor's domain. It should be a generic class name, or the class name should be passed to the component from the doctor component.

As a side note, is there any purpose in the checkboxes? I don't see any code that would handle their events. I can imagine that you intend to add some kind of "bulk actions" over the selected rows, but for the purpose of this code review, you should have either omitted the checkboxes, or post the code for handling their events too... Same for the action buttons...

\$\endgroup\$
2
  • \$\begingroup\$ That is just a dummy data. And so as the design. I was just wondering about the generic component. But thank you again for detail explanation. And these points make sense. The project I am working on. The user dashboard and the admin dashboard are using the same Table design only the data displayed to be different. The same table are design in multiple tabs. And that's why this thought came in. Rather than duplicating the same components multiple time why not avoid the redundancy and make it generic to pass only data and using the generic component here. \$\endgroup\$
    – Hamid Shah
    Commented Dec 6, 2022 at 17:59
  • \$\begingroup\$ @HamidShah it's perfectly sensible thought, however the main point stands, in general the table component must not know anything about the component that wraps it. Everything it may need to know from/about the wrapper component, must be passed by the wrapper component to the table component in a format defined by the table component. Btw does react not have any generic table component? \$\endgroup\$
    – slepic
    Commented Dec 6, 2022 at 18:07

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.