Home > Software design >  Updating a React state from child component function
Updating a React state from child component function

Time:10-16

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.

CodePudding user response:

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>
  )
}

CodePudding user response:

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!

  • Related