Using hooks. The parent component passes a value to the child component, which the child component displays. But I'd like that component editable and once the user clicks save, its new value should be passed back to parent component and is then used to update.
parent component:
const [value, setValue] = useState("");
// value is set by some function
<Child
value={value}
/>
child component:
<h2 contentEditable=true >props.value</h2>
// somehow save the value, even to a different variable, and pass it back to parent component to setValue
I have tried setting in my child component file something like
const childValue=props.value
or
const [childValue, setChildValue] = useState(props.value)
and I tried console.log on those values but they're all empty, and if I passed them to h2 in the child component, nothing displays.
--- EDIT I have tried passing the function to set value to parent but I'm struggling getting the changed value.
For child component I'd like to save either onChange or on clicking a button, but I'm missing a way to capture the new value.
parent component has a saveValue(newValue) function which I pass to child in child component
const {value, saveValue} = props;
return
<h2
onChange={() => saveValue(e.target.value)}
contentEditable=true> {value} </h2>
I have saveValue in parent component and tried changing the function to print out the argument in the console but nothing gets logged.
I also tried saving the changes with a button, I have no method of capturing the actual changes made to h2 though, as my code looks something like this:
const {value, setValue} = props;
<h2 contentEditable=true>{value}</h2>
<button onClick={()=>setValue(value)}>Save</button>
This just sets the value to the old value and not the edited one
Pass setValue to the Child component as a prop, and call it inside. For example:
const ChildComponent = ({value, setValue}) => {
return (
<>
<button onClick={() => setValue('my new value')}>
change value
</button>
<span>{value}</span>
</>
)
}
const ParentComponent = () => {
const [value, setValue] = useState("");
return <ChildComponent value={value} setValue={setValue}/>
}
You can approach this problem in 2 ways. Both the approach are basically the same thing, as you are ultimately passing a function to handle the state change.
Approach 1: Create a handler function (say handleValueChange) to manage the state change using setValue in the parent component. Then you can pass this handler function to the child component.
Parent component:
const Parent = () => {
const [value, setValue] = useState("");
function handleChange() {
// Some logic to change the "value" state
setValue("A new value");
}
return <Child value={value} handlerFunction={handleChange} />
}
Child component:
const Child = (props) => {
const { value, handlerFunction } = props;
// Utilize the props as per your needs
return (
<>
<h2 contentEditable>Value: {value}</h2>
<button onClick={handlerFunction}>Change state</button>
</>
);
};
Approach 2: Pass on the setValue function to the child component as props.
Parent component:
const Parent = () => {
const [value, setValue] = useState("");
return <Child value={value} setValue={setValue} />
}
Child component:
const Child = (props) => {
const { value, setValue } = props;
// Utilize the props to change the state, as per your needs
function handleChange() {
setValue("A new value");
}
return (
<>
<h2 contentEditable>Value: {value}</h2>
<button onClick={handleChange}>Change state</button>
</>
);
};