Gautham Muralidharan
Gautham Muralidharan

Reputation: 157

React Hooks - Changing state inside child does not reflect in parent

I have a parent component (App.jsx), Child component(Child.jsx) and a Hook (useHook hook un Hook.jsx file).

Hook.jsx below

import { useState, createContext } from "react";

export default function useHook() {
  const [one, setOne] = useState("First Option");
  const changeOne = value => {
    console.log("calling changeOne");
    console.log(value);
    setOne(value);
  };

  return {
    one,
    changeOne
  };
}

App.jsx below

import React, { useState, useContext } from "react";
import "./style.css";
import useHook from "./Hooks";
import Child from "./Child";
export default function App() {
  const details = useHook();

  return (
    <div>
      <Child />
      Inside Parent Class: {details.one}
    </div>
  );
}

Child.jsx below

import React from "react";
import "./style.css";
import useHook from "./Hooks";

export default function Child() {
  const details = useHook();
  return (
    <div>
      <form
        onChange={e => {
          details.changeOne(e.target.value);
        }}
      >
        <select id="inputState">
          <option value="First Option">First Option</option>
          <option value="Second Option">Second Option</option>
        </select>
      </form>
      Inside Child class: {details.one}
    </div>
  );
}

I want the state 'one' which gets modified inside the Child component to be used in the parent component. I imported the hook in parent component. But it looks like the both the components keep a separate copy of the state. The change I make inside the child component does not reflect in parent component. Why is it so? How I can use the state modified by the child component in the parent component.

The output when first option is chosen in dropdown

The output when second option is chosen in dropdown

Upvotes: 1

Views: 1078

Answers (1)

Oluwafemi Sule
Oluwafemi Sule

Reputation: 38982

State is already lifted in the App component. However you're creating a new one in Child component.

Forward the one and changeOne to Child component as props.

import React, { useState, useContext } from "react";
import "./style.css";
import useHook from "./Hooks";
import Child from "./Child";
export default function App() {
  const details = useHook();

  return (
    <div>
      <Child one={details.one} onChange={details.changeOne} />
      Inside Parent Class: {details.one}
    </div>
  );
}

Then declare Child component props

import React from "react";
import PropTypes from "prop-types";
import "./style.css";

export default function Child(props) {
  return (
    <div>
      <form
        onChange={e => {
          props.changeOne(e.target.value);
        }}
      >
        <select id="inputState">
          <option value="First Option">First Option</option>
          <option value="Second Option">Second Option</option>
        </select>
      </form>
      Inside Child class: {props.one}
    </div>
  );
}

Child.propTypes = {
   one: PropTypes.string.required,
   changeOne: PropTypes.func.required
}

Upvotes: 4

Related Questions