I have a React application with a Parent and a number of Child components. The child components have textboxes and other inputs that change very often(each letter type creates a state change).
I have a state in the child that takes care of these fast updates(So that the parent state doesn't change very often and performance would not be degraded).
const ParentComponent = () => {
const [globalState, setGlobalState] = useState({})
return <>
<ChildComponent value={globalState.value1}/>
<ChildComponent value={globalState.value2}/>
<ChildComponent value={globalState.value3}/>
<ChildComponent value={globalState.value4}/>
<ChildComponent value={globalState.value5}/>
<ChildComponent value={globalState.value6}/>
// I need to be able to fetch the childState on click on this button
<button />
</>
const ChildOne = ({value}) {
const [childValue, setChildValue] = useState(value)
// In my actual application, there are multiple text boxes here, so i'm maintaining one state for each input
return <input
type="text"
// this function is triggered everytime a letter is entered
onChange={(e)=> setChildValue(e.target.value}
/>
}
I need to update this data into my parent state on click of a button in the parent.
I know that we can use useRef to achieve this, but people say it's an antipattern and should be avoided. How can I do that in a reactive way?
Edit: More context. I have several tabs in the parent, and in each tab you have form fields, and you need to get the value of all the fields of the tabs in a certain moment to make a POST request with that data. I hope this would be useful
I'm not sure of the structure of your application, but the gist is to modify the global state from your child component.
You can do this by passing the setState function from the parent to the child as a prop.
import React from "react";
export default () => {
const [globalState, setGlobalState] = React.useState({
someState: {
value: ""
}
});
return (
<>
{JSON.stringify(globalState)}
<br />
<ChildComponent
value={globalState.someState.value}
setGlobalState={(val) =>
setGlobalState((prev) => ({ ...prev, someState: { value: val } }))
}
/>
</>
);
};
const ChildComponent = ({ setGlobalState, value }) => {
return (
<input
type="text"
value={value}
onChange={(e) => setGlobalState(e.target.value)}
/>
);
};
When managing complex form state, sometimes it's nice to reach for a library such as react-hook-form, final-form or something of that nature.