In this project, we'll introduce you to React by creating a small project from scratch. We'll make use of the create-react-app CLI tool to quickly generate a React boilerplate. The goal of this project is to create a simple interface for creating a list of friends with their name and picture.
- Fork and clone this repository.
- Run
sudo npm install -g create-react-app.
In this step, we'll use create-react-app to create a React boilerplate.
cdinto the root directory of the project.- Run
create-react-app ./. - Delete the
README.mdthe boilerplate generates and renameREADME.old.mdback toREADME.md.
In this step, we'll clear the boilerplate that is made for us in src/App.js.
- Open
src/App.js. - Inside of the
return()statement, replace everything with a single<div>element.
src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div>
</div>
);
}
}
export default App;In this step, we'll add the necessary elements inside the <div> element for capturing user input.
- Open
src/App.js. - Inside of the
<div>element add two inputs with lables and anAdd Friendbutton:- The first input should be for getting a URL to a picture.
- The second input should be for getting a name.
- Run
npm startto spin up a development server and see your changes.
src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div>
<span>Picture:</span>
<input />
<span>Name:</span>
<input />
<button>Add Friend</button>
</div>
);
}
}
export default App;In this step, we'll initialize state to our src/App.js. The state object will manage a list of friends and also the values for creating a new friend.
- Open
src/App.js. - Above the
rendermethod, add a new method calledconstructor. - Inside the
constructormethod, invokesuper.- This allows us to set state.
- Create a new state object, by using
this.state = {}, with the following keys:friends- An empty array.picture- An empty string.name- An empty string.
src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {
friends: [],
picture: '',
name: ''
};
}
render() {
return (
<div>
<span>Picture:</span>
<input />
<span>Name:</span>
<input />
<button>Add Friend</button>
</div>
);
}
}
export default App;In this step, we'll hook up our input elements to state. In order to do this, we'll need to create a method to update the value of picture and a method to update the value of name on state. In React, you should never update state explicitly. You should always use the built-in method this.setState().
- Open
src/App.js. - Underneath the
constructormethod, create a new method calledupdatePicture:- This method should have one parameter:
value. - This methoud should call
this.setStateto updatepicturewith the givenvalue.
- This method should have one parameter:
- Underneath the
updatePicturemethod, create a new method calledupdateName:- This method should have one parameter:
value. - This method should call
this.setStateto updatenamewith the givenvalue.
- This method should have one parameter:
- On the first input element:
- Add an
onChangeproperty that captures the event's value and callsupdatePicturewith that value.
- Add an
- On the second input element:
- Add an
onChangeproperty that captures the event's value and callsupdateNamewith that value.
- Add an
src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {
friends: [],
picture: '',
name: ''
};
}
updatePicture( value ) {
this.setState({ picture: value });
}
updateName( value ) {
this.setState({ name: value });
}
render() {
return (
<div>
<span>Picture:</span>
<input onChange={ ( e ) => this.updatePicture( e.target.value ) } value={ this.state.picture } />
<span>Name:</span>
<input onChange={ ( e ) => this.updateName( e.target.value ) } value={ this.state.name } />
<button>Add Friend</button>
</div>
);
}
}
export default App;In this step, we'll create a method for adding a friend to the friends array on state and clear the values of picture and name on state.
- Open
src/App.js. - Underneath the
updateNamemethod, create a new method calledaddFriend:- This method should use
this.setStateto add a new friend object to thefriendsarray on state.- An example of the
friend objectwould look like:{ picture: 'http://via.placeholder.com/50x50', name: 'James Lemire' }
- An example of the
- This method should use
this.setStateto clear the values ofpictureandnameon state.
- This method should use
- Add an
onClickproperty that calls theaddFriendmethod to thebuttonelement.- You must use an arrow function in order to keep the correct context of this.
src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {
friends: [],
picture: '',
name: ''
};
}
updatePicture( value ) {
this.setState({ picture: value });
}
updateName( value ) {
this.setState({ name: value });
}
addFriend() {
const { friends, picture, name } = this.state;
let newFriends = friends.slice();
newFriends.push({ picture, name });
this.setState({ friends: newFriends, picture: '', name: '' });
}
render() {
return (
<div>
<span>Picture:</span>
<input onChange={ ( e ) => this.updatePicture( e.target.value ) } value={ this.state.picture } />
<span>Name:</span>
<input onChange={ ( e ) => this.updateName( e.target.value ) } value={ this.state.name } />
<button onClick={ () => this.addFriend() }>Add Friend</button>
</div>
);
}
}
export default App;In this step, we'll add a way to see our list of friends on the DOM by mapping through the friends array on state.
- Open
src/App.js. - Just above the
return()statement, in therendermethod, create a newconstvariable calledfriends:- Map through the
friendsarray onstateto render adivelement that contains animgand aspanelement. - The
imgelement'ssrcproperty should equal the value of thefriend's picture.- Optionally you can control the maximum width/height by using the width/height propertys on the
imgelement.
- Optionally you can control the maximum width/height by using the width/height propertys on the
- The
spanelement should display thefriend's name. - Be sure to assign a
keyon the parent div. This is a requirement from React.
- Map through the
- Just below the
Add Friendbutton, use{}to break out of JSX, and render the newfriendsvariable.
src/App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {
friends: [],
picture: '',
name: ''
};
}
updatePicture( value ) {
this.setState({ picture: value });
}
updateName( value ) {
this.setState({ name: value });
}
addFriend() {
const { friends, picture, name } = this.state;
let newFriends = friends.slice();
newFriends.push({ picture, name });
this.setState({ friends: newFriends, picture: '', name: '' });
}
render() {
const friends = this.state.friends.map( ( friend, index ) => (
<div key={ `friend-${ index }-${ friend.name }` }>
<img width="100px" src={ friend.picture } />
<span>{ friend.name }</span>
</div>
));
return (
<div>
<span>Picture:</span>
<input onChange={ ( e ) => this.updatePicture( e.target.value ) } value={ this.state.picture } />
<span>Name:</span>
<input onChange={ ( e ) => this.updateName( e.target.value ) } value={ this.state.name } />
<button onClick={ () => this.addFriend() }>Add Friend</button>
{ friends }
</div>
);
}
}
export default App;If you see a problem or a typo, please fork, make the necessary changes, and create a pull request so we can review your changes and merge them into the master repo and branch.
© DevMountain LLC, 2017. Unauthorized use and/or duplication of this material without express and written permission from DevMountain, LLC is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to DevMountain with appropriate and specific direction to the original content.





