4.2 - Friend Component
We'll now add another component for rendering a friend. This is the component that we referred to at the end of the last module before the final code block. Now, let's implement it.
Friend
We have the data firing, but we have no way of showing it. We need to show the data in a list. Let's stub out everything we'll need here. We'll code with intent here, thinking about what we'll want to be able to do starting with creating a new file called FriendList.js inside the same directory as FriendListApp.js
Go into the Friend.js
file and add the following.
import React from 'react';
import FaTrashO from 'react-icons/lib/fa/trash-o'
const Friend = () => {
return (
<div>
Friend
</div>
)
}
export default Friend;
All we want this component to do is render each friend. All of the remaining logic that we still need to implement will need to happen back in our FriendListApp component, as we're keeping this one very simple. All we need to do here is figure out how to render each friend. Let's go ahead and do that how we want to. This will be our finished Friend component.
import React from 'react';
import FaTrashO from 'react-icons/lib/fa/trash-o'
const Friend = ({friend, removeFriend}) => {
return (
<div>
<li className="list-group-item">
<strong>Name:</strong> {friend.name}
<br />
<strong>Age:</strong> {friend.age}
<button onClick={(e) => {removeFriend(e, friend) }}
className="btn btn-danger trash">
<span><FaTrashO /></span>
</button>
</li>
</div>
)
}
export default Friend;
Notice that we're passing two props, one holds the friend information and we're calling it friend
, the other is the removeFriend
function, that will theoretically remove our friend. We haven't implemented this stuff in our FriendListApp component yet so we need to do that still.
Mapping to Friend
We need to iterate through all of the friends in our state and map them out to our Friend
component! This is a very common pattern you'll see in React, where you have a large dataset, and then you map it out into functional components. So here we need to do that. Inside the render, underneath the form add the following:
</form>
**** add here ****
{this.state.friends.map(friend => <Friend friend={friend} key={friend.id} />)}
**** stop adding ****
</div>
All we are doing here is mapping our state out to our friend component. Remember when mapping multiples of the same thing, React requires unique key props, so we've added one with id!
Delete Friend
Before, when we created our Friend
component we had a removeFriend
prop that we used. Let's create that method in our FriendListApp
component now. We know based on how we set up Friend
that it need to take in an event, and a friend!
Next, we can check out the API documentation here and see the structure for how we can make a delete request!
Last, we need to update our state. We can do this by filtering out the friend we passed in!
Create the following deleteFriend
method in your FriendListApp
class, put it underneath and outside of your constructor but above your render!
deleteFriend = (e, friend) => {
fetch(`${API_BASE}/${friend.id}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
}
})
.then(res => {
let tempFriends = this.state.friends.filter(fr => fr !== friend)
this.setState({friends: tempFriends})
})
}
Cool, now we just need to pass it to our Friend
component to be able to use it! Update your map in your render to look like this:
{this.state.friends.map(friend => <Friend friend={friend} key={friend.id} removeFriend={this.deleteFriend}/>)}
Now, try it out!! You should be able to add and delete friends!
componentDidMount
You may have noticed, that we have a problem. Try refreshing the app. You should get the form back, but it won't have the data:
Let's fix this! Go to FriendListApp
and let's use componentDidMount
. Add a fetch request to get our data when our component mounts! This should get our information when we refresh the page!
componentDidMount(){
fetch(API_BASE)
.then(res => res.json())
.then(response => {
console.log(response)
this.setState({friends: response})
})
}
Final Code
Here is the code for this module & app:
Friend.js
import React from 'react';
import FaTrashO from 'react-icons/lib/fa/trash-o'
const Friend = ({friend, removeFriend}) => {
return (
<div>
<li className="list-group-item">
<strong>Name:</strong> {friend.name}
<br />
<strong>Age:</strong> {friend.age}
<button onClick={(e) => {removeFriend(e, friend) }}
className="btn btn-danger trash">
<span><FaTrashO /></span>
</button>
</li>
</div>
)
}
export default Friend;
FriendListApp.js
import React, { Component } from "react";
import Friend from './Friend'
const API_BASE = "http://rest.learncode.academy/api/efa/friends";
class FriendListApp extends Component {
constructor(props) {
super(props);
this.state = { friends: [] };
}
componentDidMount(){
fetch(API_BASE)
.then(res => res.json())
.then(response => {
console.log(response)
this.setState({friends: response})
})
}
handleSubmit = event => {
event.preventDefault();
var name = this.refs.name.value;
var age = this.refs.age.value;
var friendsTemp = this.state.friends;
fetch(API_BASE, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name: name, age: age })
})
.then(res => res.json())
.then(response => {
console.log(response)
friendsTemp.push(response)
this.setState({ friends: friendsTemp })
this.refs.name.value = ""
this.refs.age.value = ""
})
}
deleteFriend = (e, friend) => {
fetch(`${API_BASE}/${friend.id}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
}
})
.then(res => {
let tempFriends = this.state.friends.filter(fr => fr !== friend)
this.setState({friends: tempFriends})
})
}
render() {
return (
<div className="main">
<div className="mainDiv">
<form onSubmit={this.handleSubmit.bind(this)}>
<h3>Enter a Friend!</h3>
<fieldset className="form-group">
<label>Friend's Name:</label>
<input
type="text"
ref="name"
name="name"
className="form-control"
/>
</fieldset>
<fieldset className="form-group">
<label>Friend's Age:</label>
<input
type="text"
ref="age"
name="age"
className="form-control"
/>
</fieldset>
<button className="btn btn-success" type="submit">
Save Friend
</button>
</form>
{this.state.friends.map(friend => <Friend friend={friend} key={friend.id} removeFriend={this.deleteFriend}/>)}
</div>
</div>
);
}
}
export default FriendListApp;
Hopefully, you guys learned more about props and state from this app! Also practice with using APIs and react!
Last updated