skip to Main Content

In reactjs, I want to get child component value at parent. Here is my code for parent and child.

child.js

import React, {useState, useEffect} from 'react';

export const Child = () => {
  const [state, setState] = useState({name: ""});
  
  const handleInputTextChange=(e)=> {
    const {name,value}=e.target;
    let newState = {...state};
    newState.name = name;
    setState(newState);
  }

  return(
    <div key="c-div" className="child">
      <input required id="child" name="childname" value={state.name} onChange={(e)=>handleInputTextChange(e)}/>
    </div>
  );
}

parent.js

import React, {useState} from 'react';
import {Child} from './child.js';

export const Parent = () => {
  
  const [names, setnames] = useState([]);
  
  const handleSubmit = async (e) => {
    e.preventDefault();
    
    const newNames = [...names];
    newNames[0] = '1st';
    newNames[1] = '2nd';
    setnames(newNames);
  }
  
  return(
    <div key="div1">
      <form name="myformname" id="myformid" onSubmit={handleSubmit}>
        <Child />
        <Child />
        <button> Print Child Names </button> 
      </form>
      The first child names are <b>{names[0]}</b> and <b>{names[1]}</b>
    </div>
  );
}

I am finding multiple issues in it.
If I type in textfield of child, its not showing, its showing always childname as value.

My main question in such cases, how can I get the value from child at parent.

I will be more interested to know if I can get value like child1.getName(), child2.getName() kind of function so that I will not have to make use of callbacks or state variable in parent.

2

Answers


  1. You can not access child component directly from the parent one. For basic use, You can try with forwardRef, which pass ref of child component to parent.

    reference for forwardRef

    For complex logic, We use context api or any other global state management library.

    Login or Signup to reply.
  2. One way to pass data from a child to a parent component is to define a callback function in the parent component and pass it down to the child component as a prop. The child component can then call this function with the data it wants to pass up to the parent.

    Parent.js

    import React, { useState } from 'react';
    import { Child } from './Child';
    
    export const Parent = () => {
      const [names, setNames] = useState(['', '']);
    
      const handleChildNameChange = (updatedState, index) => {
      const newNames = [...names];
      newNames[index] = updatedState.name;
      setNames(newNames);
    };
    
    const handleSubmit = async (e) => {
       e.preventDefault();
      // This part remains the same as you provided
      const newNames = [...names];
      newNames[0] = '1st';
      newNames[1] = '2nd';
      setNames(newNames);
     };
    
     return (
       <div key="div1">
        <form name="myformname" id="myformid" onSubmit={handleSubmit}>
        {/* Pass props to each Child */}
        <Child onNameChange={(updatedState) => 
                handleChildNameChange(updatedState, 0)} />
        <Child onNameChange={(updatedState) => 
                handleChildNameChange(updatedState, 1)} />
        <button>Print Child Names</button>
      </form>
        The first child name is <b>{names[0]}</b> and the second child name is 
             <b>{names[1]}</b>
       </div>
     );
    };
    

    Child.js

    import React, { useState } from 'react';
    
    export const Child = ({ onNameChange }) => {
       const [state, setState] = useState({ name: '' });
    
       const handleInputTextChange = (e) => {
       const { name, value } = e.target;
       let newState = { ...state };
       newState[name] = value;  // Use name as key to update state dynamically
       setState(newState);
       onNameChange(newState); // Call callback with updated state
      };
    
     return (
       <div key="c-div" className="child">
        <input
         required
         id="child"
         name="name"  // Fixed the name attribute to "name"
         value={state.name}
         onChange={(e) => handleInputTextChange(e)}
       />
     </div>
     );
     };
    

    Explanation:

    Child Component (Child.js):

    Added a name attribute to the field to correctly capture its value in the handleInputTextChange function.

    Modified handleInputTextChange to update state[name] dynamically based on the name attribute of the input field.

    Added a call to onNameChange(newState) to invoke the callback provided by the parent whenever the input changes.

    Parent Component (Parent.js):

    Introduced names state to store the names entered in both Child components.

    Created handleChildNameChange function to update the names state array based on the index of the child component that is updated.

    Passed onNameChange callback to each Child component, which calls handleChildNameChange with the updated state and index.

    This structure ensures that each Child component can independently update the Parent component’s state (names) when the input value changes, and the parent component manages the overall state of names. Now, when you submit the form or interact with the components, the parent component will have access to the names entered in each child component.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search