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,
- one way is to create a state in the parent component of both children components.
- The second way is to initialise React context.
- Otherwise, there are external libraries such as redux for global sharing states.