Home > Software engineering >  Pass data between components React
Pass data between components React

Time:10-29

I'm new with React and I want to move an object data from one child component to another, this is my code:

import React from "react";
import SiteRow from "./SiteRow";
import AlertList from "../Alerts/AlertList";
import data from "../../static/fixtures/data.json";

const SiteList = () => {
    return (
      <div className="row">
        <div className="col-8">
          <table className="table table-bordered">
            <thead>
              <tr>
                <th scope="col">Site</th>
                <th scope="col">Alerts</th>
                <th scope="col">Savings</th>
                <th scope="col">Uptime</th>
                <th scope="col">Power</th>
              </tr>
            </thead>
            <SiteRow sites={data.sites} />
          </table>
        </div>
        <AlertList />
      </div>
    );  
};

export default SiteList;

When I click in a row in the SiteRow component must show data in a child component AlertRow from AlertList, I've been looking for this but I'm stuck, any idea?

Thanks.

I was reading about React Context, but I don't got the idea for sharing the data.

CodePudding user response:

The simplest way is to place the state in their common ancestor, in this case SiteList.

In SiteRow you create a callback prop (onSelectSite in the demo below) that will be called every time a row is clicked. In SiteList you will use that callback to update the state (selectedSite in the demo below). You will then pass such state to AlertList.

See working demo:

const data = {sites: [{site: 'click me aaa'}, {site: 'click me bbb'}]};
const AlertList = ({ site }) => {
  return (
    <div>
      <hr />
      AlertList - selected site: {JSON.stringify(site)}
    </div>
  );
}
const SiteRow = ({ sites, onSelectSite }) => {
  return (
    <tbody>
      {sites.map(s => <tr onClick={e => onSelectSite(s, e)}><td>{s.site}</td></tr>)}
    </tbody>
  );
}

const SiteList = () => {
    const [selectedSite, setSelectedSite] = React.useState(null);
    const handleSelectedSite = (site) => {
      setSelectedSite(site);
    }
    return (
      <div className="row">
        <div className="col-8">
          <table className="table table-bordered">
            <thead>
              <tr>
                <th scope="col">Site</th>
                <th scope="col">Alerts</th>
                <th scope="col">Savings</th>
                <th scope="col">Uptime</th>
                <th scope="col">Power</th>
              </tr>
            </thead>
            <SiteRow sites={data.sites} onSelectSite={handleSelectedSite} />
          </table>
        </div>
        <AlertList site={selectedSite} />
      </div>
    );  
};

ReactDOM.createRoot(document.getElementById('app')).render(<SiteList />);
table, tr, td {
  border: 1px solid black;
  border-collapse: collapse;
}
td { color: blue; cursor: pointer; }
<script type="text/javascript" src="//unpkg.com/react@18/umd/react.production.min.js"></script>
<script type="text/javascript" src="//unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

<div id="app"></div>

If you have a very deep component tree. There are other ways to make this passing of props simpler, such as Context or libraries like Redux.

CodePudding user response:

There are several ways to do that,

  1. one way is to create a state in the parent component of both children components.
  2. The second way is to initialise React context.
  3. Otherwise, there are external libraries such as redux for global sharing states.
  • Related