2

I am wondering if there is a way to update a state in a parent functional component from a child component using a function, something similar to the below example for class components:

<ParentComponent name={ this.state.name } email={ this.state.email } setValues={ ( state, value ) => { this.setState({ [state] : value }) }} /> 
<ChildComponent> <input type={ 'text' } value={ this.props.name } onChange={ ( event ) => { this.props.setValues( 'name', event.target.value ) }} /> <input type={ 'email' } value={ this.props.email } onChange={ ( event ) => { this.props.setValues( 'email', event.target.value ) }} /> </ChildComponent> 

I need something similar in a functional component using Hooks if possible.

Let me know if more information is required.

Thanks in advance.

1
  • Yes of course you can do this with function components. You do it the exact same way. No code in your example requires classes (except this.setState but that simply becomes the relevant state updater function) - in fact not a single class is even shown in your code! Commented Oct 16, 2021 at 12:46

2 Answers 2

4

just like the class case, Pass the state changer function as props to the child component and do whatever you want to do with the function

import React, {useState} from 'react'; const ParentComponent = () => { const[state, setState]=useState(''); return( <ChildConmponent stateChanger={setState} /> ) } const ChildConmponent = ({stateChanger, ...rest}) => { return( <button onClick={() => stateChanger('New data')}></button> ) } 
Sign up to request clarification or add additional context in comments.

4 Comments

In this case I need to pass through every state changer function as a prop? So if I have 3 states I need to change, I need to pass through all 3. Which is what I am currently doing, but was wondering if there was a way to pass one global function rather than passing through all 3. No train smash if one can't, I am just curios.
Yes. You can use react context. If you are not familiar with it, read this: reactjs.org/docs/context.html
Awesome, will have a look into this further using context, never thought of using a context outside the basic usage of theming and auth settings.
You can also use useReducer and pass down the dispatcher function if you want to allow changing several pieces of state without passing down a setter for every one.
0

You can possibly implement some reducer like logic.

import React, { useState } from "react"; const ParentComponent = () => { const [count, setCount] = useState(0); const [name, setName] = useState("John"); const [otherState, setOtherState] = useState(false); const changeState = (state, value) => { // Pass state as string switch (state) { case "count": return setCount(value); case "name": return setName(value); case "otherState": return setOtherState(value); } }; return <ChildConmponent stateChanger={changeState} />; }; const ChildConmponent = ({ stateChanger, ...rest }) => { return ( <div> {/* Change count */} <button onClick={() => stateChanger("count", 10)}></button> {/* Chnage name */} <input type="text" onChange={(event) => stateChanger("name", event.target.value)} /> {/* Change other state */} <input type="checkbox" onChange={(event) => stateChanger("otherState", event.target.checked)} /> </div> ); }; 

However, I really wouldn't recommend this approach. Checkout useReducer and useContext hooks, which should provide you with a much better solution to this problem.

Have a nice day!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.