I have two components. My parent component, IntakeDetails, calls the child component, ActionsTab, within a TabPanel. The Actions component contains a table and Dialogs. When I close any Dialog in Actions, I want to call a function in IntakeDetails called fetchDetails
. How would I go about doing this?
fetchDetails
pulls some crucial data that is changed in backend api's when certain criteria in ActionsTab are met. I want to call fetchDetails
every time there is a successful update in ActionsTab.
This is a basic overview of my code.
IntakeDetails
export default function IntakeDetails2() {
const [details, setDetails] = useState("");
const [busy, setBusy] = useState(false);
const [value, setValue] = useState(1); // Tab panel index
const fetchDetails = async () => {
setBusy(true);
if (value === 1) {
const response = await fetch(`/api/fiscalyears/${fy}/intakes/${params.id}/details2`);
const detailsResp = await response.json();
setDetails(detailsResp);
}
setBusy(false);
};
....
return (
<Tabs value={value} onChange={handleChange} aria-label="basic tabs example">
<Tab label="Solutioning" className={classes.tabs} />
<Tab label="Actions" className={classes.tabs} disabled={details?.IntakeID === 0} />
</Tabs>
<TabPanel value={value} index={1}>
....
</TabPanel>
<TabPanel value={value} index={4}>
<ActionsTab />
</TabPanel>
);
}
ActionsTab
function ActionsTab() {
...
const updateAction = async (e) => {
e.preventDefault();
const updateResponse = await fetch(`/api/actions/${action.Id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(action),
});
const updateActionResp = await updateResponse.json();
if (updateResponse.ok) {
setSuccessOpen(true);
// I would like to call the fetchDetails() function here
} else {
setErrorMessage(updateActionResp?.error);
setErrorOpen(true);
}
};
const onMessageClose = () => {
setSuccessOpen(false);
fetchActions();
};
}
CodePudding user response:
Add your callback as a prop in ActionsTab
, and pass it from IntakeDetails
.
Example:
function ActionsTab(props) { // props get passed as the 1st argument from parent
// ...
const updateAction = async (e) => {
e.preventDefault();
const updateResponse = await fetch(`/api/actions/${action.Id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(action),
});
const updateActionResp = await updateResponse.json();
if (updateResponse.ok) {
setSuccessOpen(true);
// add your function call here - this will call the func
// that was passed from the parent
props.onUpdate() // you can pass arguments here if you want
} else {
setErrorMessage(updateActionResp?.error);
setErrorOpen(true);
}
};
// ...
}
And then:
export default function IntakeDetails2() {
// ...
return (
// ...
<TabPanel value={value} index={4}>
{/* pass the function you want to call when ActionsTab triggers update */}
<ActionsTab onUpdate={() => fetchDetails()} />
</TabPanel>
)
}
CodePudding user response:
The simplest thing you can do is to pass the fetchDetails
function as property to your ActionsTab
->
<TabPanel value={value} index={4}>
<ActionsTab fetchDetails={fetchDetails} />
</TabPanel>
After you used destructure it from your props ->
function ActionsTab({ fetchDetails }) {
you can use it within updateAction
->
if (updateResponse.ok) {
setSuccessOpen(true);
// I would like to call the fetchDetails() function here
await fetchDetails()
}
FYI: I see that you want Error handling. I suggest you wrap your axios call in try and catch to handle any error while fetching.