Skip to content

Instantly share code, notes, and snippets.

@jsjoeio
Created February 17, 2018 17:41
Show Gist options
  • Save jsjoeio/a5c1da4174b7b090b718320a5a9e9c67 to your computer and use it in GitHub Desktop.
Save jsjoeio/a5c1da4174b7b090b718320a5a9e9c67 to your computer and use it in GitHub Desktop.
JS - React - passing data from child to parent component
//To give some context, this is an example taken from Thinkful's curriculum. This section of the curriculum uses a simple React app that creates a clone of Trello.
//We will be looking at two components: an AddForm component (child) and a List component (parent)
//This gist aims to show how we pass data from the child component to the parent component. I will do this by adding in comments throughout the code for each component.
//The code for the child component.
import React from 'react';
import './add-form.css';
export default class AddForm extends React.Component {
constructor(props) {
super(props);
this.state = {
editing: false
}
}
onSubmit(event) {
event.preventDefault();
const text = this.textInput.value.trim();
/*
This is the KEY part. We call this "onSubmit" function when the form is submitted.
We first use an if statement to check: 1. is there text being submitted? 2. does the component have an onAdd prop passed to it when it's called/created. If both are true, then pass the text as an argument to the onAdd prop. This will send our data from the child to the parent component. Now let's look at the parent component.
*/
if (text && this.props.onAdd) {
this.props.onAdd(text);
}
this.textInput.value = '';
}
setEditing(editing) {
this.setState({
editing
});
}
render() {
if (!this.state.editing) {
return (
<div className="add-button"
onClick={() => this.setEditing(true)}>
<a href="#">Add a {this.props.type}...</a>
</div>
);
}
return (
<form className="card add-form" onSubmit={(e) => this.onSubmit(e)}>
<input type="text" ref={input => this.textInput = input} />
<button>Add</button>
<button type="button" onClick={() => this.setEditing(false)}>
Cancel
</button>
</form>
);
}
}
//The code for the parent component
import React from 'react';
import Card from './card';
import AddForm from './add-form';
export default class List extends React.Component {
constructor(props) {
super(props);
this.state = {
cards: []
}
}
addCard(text) {
//this method adds a card using the text from the child component. AWESOME!
this.setState({
cards: [...this.state.cards, {
text
}]
});
}
render() {
const cards = this.state.cards.map((card, index) =>
<li key={index}>
<Card {...card} />
</li>
);
return (
<div>
<h3>{this.props.title}</h3>
<ul className="list">
{cards}
<li>
/*
The key part here is where we create the AddForm component.
We pass two props: 1. type="card" to know that it's an AddForm for cards (as opposed to for lists) 2. onAdd prop. This is a function, which takes one parameter: text. Then it has a callback function which is tied to the List component (parent component), which is why we use this.addCard. We pass the text value to the addCard function.
Now stop for a second. You're probably thinking, "Wait, where is the text coming from?"
If we go back to the child component, we had `this.props.onAdd(text);`. So the text in the child component gets passed to the parent component so we can use it in the addCard function. WOOT WOOT!
*/
<AddForm
type="card"
onAdd={text => this.addCard(text)}
/>
</li>
</ul>
</div>
);
}
}
List.defaultProps = {
title: ''
};
@ephraimduncan
Copy link

Wow, but I'm still confused about this passing from child to parent thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment