If you've gone through the basics of react you would have immediately noticed the Component architecture that react follows.
<ParentComponent>
<ChildComponent />
</ParentComponent>
Most of the time, these components share data among themselves and sometimes one of the components would like to change the state of the other.
Let's take a simple form as an example to explain how this would be done. You can have a look at the final result in the sandbox below:
Components
Let's go through the components one after the other, we'll go with the parent first cos that's how it's done in Africa
Honour The Parent
const Form = () => {
const [parentState, setParentState] = useState({
name: "",
email: "",
tel: ""
});
const updateState = (key, value) => {
setParentState({ ...parentState, [key]: value });
};
return (
<>
<form>
<InputField field="name" updateState={updateState} />
<InputField field="email" updateState={updateState} />
<InputField field="tel" type="number" updateState={updateState} />
</form>
<h1>Current Parent State</h1>
<pre>{JSON.stringify(parentState, null, 2)}</pre>
</>
);
};
First, we declare the initial parent state with empty field for name, email and telephone which we would be collecting from the user.
Secondly, we declare the function updateState
which takes in a key, value
pair of the current input field that's being updated and propagates the value to the parentState. This function is passed down as a prop to each of the child components and allows the communicate effectively with their parents, which is what you would want in an ideal parent/child relationship.
The last section just prints out the current parent state so you could see the changes as they happen on the screen real time. The parentState is transformed to a JSON string and given an indentation of 2 and the surrounding pre tags make it pretty.
Children are a Blessing
const InputField = ({ field, type, updateState }) => {
const [value, setValue] = useState("");
const props = {
value,
onChange: (e) => {
setValue(e.target.value);
updateState(field, e.target.value);
}
};
return (
<label style={{ textTransform: "capitalize", display: "block" }}>
{field}
<input type={type} {...props} />
</label>
);
};
Each child takes in three or less props. The first is a field
which could be seen as their name, the second is type
which could be like a special function they have and not all the children have special functions. The last is updateState
which controls how each child communicates with their parents.
The first section declares each child's state, you know what they've got in them, their value. It starts out as empty till you start filling them up.
Then they have their props
which could be seen as their properties. This is common amongst all the children, it's their value, and what happens anytime that value is changed. An event, e
occurs and then the target
of that event has a new value
which becomes the child's value. updateState
let's the child's parent know what's happening to each particular child based on the field
or name.
Conclusion
Hope this post was helpful in letting you find an easy way to communicate between parent and child components in react. I also hope you had as much fun reading this as I did writing it.
If you have any questions concerning this, feel free to reach out to me for more information.