FAQ: Child Components Update Their Parents' state - Receive the Event Handler

This community-built FAQ covers the “Receive the Event Handler” exercise from the lesson “Child Components Update Their Parents’ state”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Web Development

Learn ReactJS: Part II

FAQs on the exercise Receive the Event Handler

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Why would we define changeName in the parent class instead of baking the functionality into the child? is it so that we can update the parent component?

because the child component is stateless. Its a design pattern, data flows one way (from parent to child).

A React component should use state to store information that the component itself can change, however, if every component has there own state, you will loose overview pretty quickly (if you have a couple dozen components). And your code would be really difficult to maintain and change.

lets say you build an application with react, If your application gets big enough, it would be wise to use redux to manage the state of your application in a single place.

this is always the problem (problem, not your fault :wink: ) with the kind of question you just asked. These design patterns start really to pay off when your application gets bigger, not when you have two components like in the lesson.

9 Likes

I passed a function changeName to the select of child but the system return an error. I can’t go on.

import React from 'react';

export class Child extends React.Component {
  render() {
    return (
      <div>
        <h1>
          Hey my name is {this.props.name}!
        </h1>
        <select id="great-names" onChange={this.changeName}>
          <option value="Frarthur">
            Frarthur
          </option>

          <option value="Gromulus">
            Gromulus
          </option>

          <option value="Thinkpiece">
            Thinkpiece
          </option>
        </select>
      </div>
    );
  }
}
5 Likes

Hi, I was struggling with this too at first.

You need to pass onChange down to the child from the parent because that is where changeName is contained in the Parent render. onChange is accessible through props just like name is above in the

so you need to make it this.props.onChange.

Your <select> tag should look like this:

<select id="great-names onChange={this.props.onChange}>

I hope that helps!

10 Likes

Oh. I did not think about it. Thank you

Thank you for that, really helps.

This wasn’t really made clear from earlier steps.

I feel like this exercise is very muddy. Not on par with Codecademy’s other exercises which are easy to follow.

5 Likes

Yeah, I’m glad I’m not the only one who thought so. I’d like a better explanation of this exercise. Also, I hear binding is outdated

4 Likes

Is it possible to to pull multiple values from an event handler? Here we pulled name and used handleChange(e) to set name = e.target.value. But what if I wanted to do multiple parameters. Would there be a way to do that with event handlers? Like lets say if I wanted to do name and age, could I do it with the same function with something like e.target.value[0] , or would I need two separate event handlers with individual functions?

I haven’t done react in ages, but i suppose you could use a single function, but then the function you would have to determine based on id or name of the input field, which fields you are dealing with. e (event) also contains that information if i am not mistaken

We can just pass the event to the parent’s function from the child, that way we won’t have to add another function to the child class. That seems like the better way to do it, although it doesn’t want me to do it.

import React from 'react';
import ReactDOM from 'react-dom';
import { Child } from './Child';

class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = { name: 'Frarthur' };
    this.changeName = this.changeName.bind(this);
  }

  changeName(event){
    this.setState({name: event.target.value})
  }
  
  render() {
    return <Child name={this.state.name} onChange={this.changeName} />
  }
}

ReactDOM.render(
	<Parent />,
	document.getElementById('app')
);
2 Likes

Thanks a lot , it wasn’t clear what was asked this step.

After completing step 1 of this module, I’m confused how “Frarther” still shows up on the screen after changing the selection and triggering the onChange event which calls changeName in Parent.js. I thought that the message on the screen after changing the selection would be: “Hey my name is #the event object#!”. Instead it’s the still the original statement: “Hey my name is Frarthur!”. I presumed the on-screen message would become the former because changeName is called with the event argument so its parameter “newName” would = event within the changeName function. This would mean when it gets to this line in changeName:

this.setState({name: newName});

it would essentially be calling this.setState({name: eventParameter}); which would set the name property of the state of the Parent component to the event. When Parent re-renders and triggers the render method of Child, this line in the Child render method:

Hey my name is {this.props.name}!

would essentially evaluate to “Hey my name is {theTriggeredEvent}!” which would output to the screen the message: “Hey my name is #the event object#!”

What am I not understanding correctly about this? Why is the message on the screen still “Hey my name is Frarthur!”

1 Like

If you try looking at the console message using Google Chrome DevTools or something, you’ll probably get an error message like this:

Uncaught Invariant Violation: Objects are not valid as a React child…

If I understand correctly, this error occurs because React cannot render objects directly. So it seems that rendering stops before displaying in the browser.

For step 4 of this exercise (Receive the Event Handler), why declare a separate handle function? Why not use an anonymous function?

<select id="great-names" onChange={(e) => this.props.onChange(e.target.value)}>

I get it may be useful for more complicated use cases but, in this example it seems unnecessary.

An alternative solution for this exercise is that we can use an arrow function directly and call this.props.onChange in it. in arrow functions, we don’t even need to bind.

import React from "react";

export class Child extends React.Component {
  render() {
    return (
      <div>
        <h1>Hey my name is {this.props.name}!</h1>
        <select 
          onChange={(e) => this.props.onChange(e.target.value)}
          id="great-names"
        >
          <option value="Frarthur">Frarthur</option>

          <option value="Gromulus">Gromulus</option>

          <option value="Thinkpiece">Thinkpiece</option>
        </select>
      </div>
    );
  }
}
1 Like

may you tell me the name of this pattern? in case I want to read more about it which keywords I should use to search?

This seems like a reasonable article:

https://programmingwithmosh.com/javascript/stateful-stateless-components-react/

1 Like

Thank you too much :smiley:.

I also had this idea, so I came to see if someone else thought the same hahaha … let’s leave it as a design pattern …