Email - harun.bspt2014@gmail.com Phone - +8801717615827

Pass-props-from-Child-to-parent-Component-communication

We need a way for the child component to tell the parent component to update without breaking one-way data flow. Since we are using local state, we need a way for the child component to tell the parent component to call setState. One way to solve this is to create a function in the parent component and add it as a property on the object passed to our render prop. Then whenever the child component needs to update state, it calls this function.

This function then executes in the parent context and calls setState. Once setState is run, if any state value has changed, those new values propagate down into our render prop and the child component now receives the new value.

For passing from child to parent – pass one callback function from parent to child and then use this passed-down function in the child to send something back to parent.

Same tutorial – https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17

A> Define a callback in my parent which takes the data I need in as a parameter.

B> Pass that callback as a prop to the child.

C> Call the callback using this.props.[callback] in the child (insert your own name where it says [callback] of course), and pass in the data as the argument.

Here’s what that might look like if I had data in ToDoItem (the Child Component) that I need to access in ToDoList(The parent Component) : And the data that ToDoList will receive from the child ToDoItem is given a variable name listInfo for example.

// Parent component
class ParentToDoList extends React.Component {

    myCallback = (dataFromChild) => {
     //  [...we will use the dataFromChild here...]
    },
    render() {
        return (
            <div>
                 <ChildToDoItem callbackFromParent={this.myCallback}/>
            </div>
        );
    }
}

// Now from within ToDoItem (The Child Component) we can pass something to callbackFromParent (the prop that was given the value or assigned the value of the CB function that was defined in the parent ) :

// Child component
class ChildToDoItem extends React.Component {
    someFn = () => {
        // [...somewhere in here I define a variable listInfo which I think will be useful as data in my ToDoList component...]
        this.props.callbackFromParent(listInfo);
    },
    render() {
        [...]
    }
};

ToDoList will now be able to use listInfo within it’s myCallback function!

But what if I want to use ‘listInfo’ in a different function within ToDoList, not just in myCallback so I get ‘listInfo’ as a regular variable in the parent component ? With the above implementation, I would only have access as a parameter passed into that one specific method.

Easy: set this parameter as a state within ToDoList. You can almost think of it as creating a variable within the scope of ToDoList that all the methods within that component can access. In that case my code defining ToDoList might look something like:

class ToDoList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            listDataFromChild: null
        };
    },
    myCallback = (dataFromChild) => {
        this.setState({ listDataFromChild: dataFromChild });
    },
    otherFn = () => {
       // ..within this other function now I still have access to this.state.listDataFromChild...
    }
    render() {
        return (
            <div>
                 <ToDoItem callbackFromParent={this.myCallback}/>
                 [...now here I can pass this.state.listDataFromChild as a prop to any other child component...]

            </div>
        );
    }
});

Another Implementation of the above concept in below file –

https://github.com/rohan-paul/Fetch-Github-Profile/blob/master/simple-version-without-using-redux/src/App.js

App.js is Parent and SearchProfile and Profile are the children.

Define a callback in my parent which takes the data I need in as a parameter.

Pass that callback as a prop to the child (see above).

Call the callback using this.props.[callback] in the child (insert your own name where it says [callback] of course), and pass in the data as the argument.

fetchProfile() is a callback function defined in parent. This takes the data I need as an argument. But the data will come from the child component SearhProfile

So, I pass this callback function to the child-Component SearchProfile as a prop, with the below line

<SearchProfile fetchProfileBoundFunction={this.fetchProfile.bind(this)}/>

Call the callback (fetchProfileBoundFunction) using this.props.[callback] in the child and pass in the data as the argument. So in SearchProfile I do < this.props.fetchProfileBoundFunction(username) >

Even Another Implementation of the above concept in below file –

https://github.com/rohan-paul/check-pack-items-before-travel/blob/master/src/components/Items.js

updateSearchTerm() in parent component Items.js – Fundamental explanation why I need it at all – Because, here, my most fundamental need is to change the searchTerm ( the parent state ) to whatever I type. But then, I am updating this searchTerm from the child and passing down ‘searchTerm’ as a prop from parent to child. And Prop is immutable, so I can not directly change ‘searchTerm’ in the Filter.js So, instead I can give the child a function ( updateSearchTerm() in this file ), that the child can call, and that function can manipulate the state.

// parent component

class Items extends Component {
  constructor(props) {
    super(props);
    this.state = {
      searchTerm: ""
    };
  }

  updateSearchTerm = searchTerm => {
    this.setState({
      searchTerm
    });
  };
  /* In above, I am using object destructuring syntax. So the single 'searchTerm' is equivalent to doing < searchTerm: searchTerm >  Which effectively means tha I am telling setState 'Hey take the searchTerm argument of updateSearchTerm() function and set them to be the value of the key-value pair of state (which is an object and both the key and the value is called 'searchTerm' ).
   */

  render() {
    const { title, items, onRemove, onToggle } = this.props;

    return (
      <section className="Items">
        <h2>
          {title} ({items.length})
        </h2>
        <Filter
          searchTerm={this.state.searchTerm}
          onChange={this.updateSearchTerm}
        />
        {items
          .filter(item =>
            item.value
              .toLowerCase()
              .includes(this.state.searchTerm.toLowerCase())
          )
          .map(item => (
            <Item
              key={item.id}
              onToggle={onToggle}
              onRemove={() => onRemove(item)}
              item={item}
            />
          ))}
      </section>
    );
  }
}

And then in child component, I have the below. SO ITS DATA-DOWN ACTIONS-UP KIND OF FLOW

The flow of data passing from child to parent is as below

A> onChange() is passed from parent to child.

B> event.target.value is triggerd in the Child whenever the user types something in the input field.

C> This event.target.value is captured in the ‘value’ variable and passed as the argument to onChange() – the function that was passed from parent to child. And onChange() is also invoked as soon as user starts typing something in the input filed.

C> And now ‘updateSearchTerm’ is executed in parent as well > setState() executed > and parent’s state gets changed.

// child component

class Filter extends Component {
  // note onChange and searchTerm were the props that were handed-down from Items.js
  // and so first to access / consume it inside the child I have to do a this.props
  // And because this is a Functional Component without constructor, so I don't need to
  // declare super(props) before using this.props
  // the onChange() inside handleChange() is NOT an 'onChange' event attribute but the props passed from parent Items.js to Filter.js
  // but the onChange inside return() within the <input/> element is the onChange event attribute.

  handleChange = event => {
    const { onChange } = this.props;
    const value = event.target.value;
    onChange(value);
  };

  render() {
    const { searchTerm } = this.props;
    return (
      <input
        className="Items-searchTerm"
        value={searchTerm}
        onChange={this.handleChange}
      />
    );
  }
}

This is the easiest direction in React to transfer data. If I have access to data in my parent component that I need my child component to have access to, I can pass it as a prop to the child when I instantiate it within the parent.

In my example, if I need to pass something from the parent App Component to the ToDoList Child component:

class App extends React.Component {
  render() {
    // [... somewhere in here I define a variable listName which I think will be useful as data in my ToDoList component...]

    return (
      <div>
        <InputBar />
        <ToDoList listNameFromParent={listName} />
      </div>
    );
  }
}

Then in the ToDoList child component I will access / consume the passed-in data from parent like below

class ToDoList extends React.Component {
  render() {
    const { listNameFromParent } = this.props;
    return (
      <div>
        <ul>{listNameFromParent}</ul>
      </div>
    );
  }
}

However if the above ToDoList child-component was declared as a ES6-Class component with a constructor – We had to call super(props) inside the constructor BEFORE BEING ABLE TO use this.props

The reason why this cannot be allowed before super() is because this is uninitialized if super() is not called. However even if we are not using this we need a super inside a constructor because ES6 class constructors MUST call super if they are subclasses. Thus, you have to call super() as long as you have a constructor. (But a subclass does not have to have a constructor).

Another example of passing data from parent to child

// RecipeList is the parent - note I am passing 5 props down to child

class RecipeList extends Component {
  render() {
    return (
      <div style={{ display: "flex" }}>
        {this.props.recipes.map((item, index) => (
          <Recipe
            key={index}
            title={item.title}
            ingredients={item.ingredients}
            instructions={item.instructions}
            img={item.img}
          />
        ))}
      </div>
    );
  }
}

// And then Recipe is the child - note,

class Recipe extends Component {
  render() {
    const { title, img, instructions } = this.props;

    const ingredients = this.props.ingredients.map((ing, index) => (
      <li key={index}>{ing}</li>
    ));

    return (
      <div className="recipe-card">
        <div className="recipe-card-img">
          {" "}
          <img src={img} alt={title} />{" "}
        </div>
        <div className="recipe-card-content">
          <h3 className="recipe-title">Reciepe {title}</h3>
          <ul> {ingredients} </ul>
          <h4>Instructions:</h4>
          <p>{instructions}</p>
        </div>
      </div>
    );
  }
}

Another Example – Passing simple Props from Parent to Child — where the prop is not a function

Inside the parent component, just do <ChildComponent propName={this.props.propName} /> and then inside the child component just do {this.props.propName}

Implemented example

class App extends React.Component {
  render() {
    return (
      <div>
        <Profile
          name={this.state.profileData.name}
          imgURL={this.state.profileData.imgURL}
        />
        <Followers followerList={this.state.profileData.followerList} />
      </div>
    );
  }
}

class Profile extends React.Component {
  render() {
    return (
      <div>
        <h3>{this.props.name}</h3>
        <img src={this.props.imgURL} />
      </div>
    );
  }
}

class Followers extends React.Component {
  render() {
    var followers = this.props.followerList.map(function(follower, index) {
      return <li key={index}>{follower}</li>;
    });

    return (
      <div>
        <h5>My followers:</h5>
        <ul>{followers}</ul>
      </div>
    );
  }
}

React component communication

https://www.javascriptstuff.com/component-communication/

Basic Theory – https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17

Also my somewhat detailed-comments in code – https://github.com/rohan-paul/Fetch-Github-Profile/blob/master/simple-version-without-using-redux/src/App.js

And a great live example https://jsbin.com/tipixiy/edit?js,output

Further Sources / Reading

1> Example of data passing from child to parent by invoking a CB (defined in parent ) in child and updating state in parent

https://github.com/rohan-paul/check-pack-items-before-travel/blob/master/src/components/NewItem.js

2> React component communication

https://www.javascriptstuff.com/component-communication/

3> Simple example of passing function (a function that has a setState() it it) from parent to child and invoking it in the child – thereby triggering state change in the parent (e.g. on button-click in the child)

https://www.youtube.com/watch?v=AnRDdEz1FJc

Dr. Harun
Dr. Harun

Dr. Md. Harun Ar Rashid, MPH, MD, PhD, is a highly respected medical specialist celebrated for his exceptional clinical expertise and unwavering commitment to patient care. With advanced qualifications including MPH, MD, and PhD, he integrates cutting-edge research with a compassionate approach to medicine, ensuring that every patient receives personalized and effective treatment. His extensive training and hands-on experience enable him to diagnose complex conditions accurately and develop innovative treatment strategies tailored to individual needs. In addition to his clinical practice, Dr. Harun Ar Rashid is dedicated to medical education and research, writing and inventory creative thinking, innovative idea, critical care managementing make in his community to outreach, often participating in initiatives that promote health awareness and advance medical knowledge. His career is a testament to the high standards represented by his credentials, and he continues to contribute significantly to his field, driving improvements in both patient outcomes and healthcare practices.

Translate »
Register New Account