I have issues with communication between a parent and a child component.
I would like the parent (Host) to hold his own state. I would like the child (Guest) to be passed that state and modify it. The child has his local version of the state which can change however the child wants. However, once the child finishes playing with the state, he passes it up to the parent to actually "Save" the actual state. How would I correctly implement this?
Issues from my code:
on the updateGlobalData handler, I log both data and newDataFromGuest and they are the same. I would like data to represent the old version of the data, and newDataFromGuest to represent the new
updateGlobalData is being called 2X. I can solve this by removing the updateGlobalData ref from the deps array inside useEffect but I don't want to heck it.
My desired results should be:
- the data state should hold the old data until updateGlobalData is called
- I want updateGlobalData to be fired only once when I click the button
Code from Codesandbox:
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const Host = () => {
const [data, setData] = useState({ foo: { bar: 1 } });
const updateGlobalData = newDataFromGuest => {
console.log(data);
console.log(newDataFromGuest);
setData(newDataFromGuest);
};
return <Guest data={data} updateGlobalData={updateGlobalData} />;
};
const Guest = ({ data, updateGlobalData }) => {
const [localData, setLocalData] = useState(data);
const changeLocalData = newBarNumber => {
localData.foo = { bar: newBarNumber };
setLocalData({ ...localData });
};
useEffect(() => {
updateGlobalData(localData);
}, [localData, updateGlobalData]);
return (
<div>
<span>{localData.foo.bar}</span> <br />
<button onClick={() => changeLocalData(++localData.foo.bar)}>
Increment
</button>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<Host />, rootElement);