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 ) 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.
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
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.
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!”
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.
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>
);
}
}