This will be a quick down and dirty tutorial on making a to-do list using React. If you’re anything like me and todo lists just really get you fired up, you can take a sneak peek at this bad boy in all it’s finished glory right here.
…I know pretty amazing stuff right?


This app is already bootstrapped using Create React App, and I have added some minor styling with CSS. If you’d like to add your own styling to things, you can always start from scratch here! React also has some really great Docs that I highly recommend reading which can be found at Reactjs.org
Get Started with React
- Clone this repository
$ git clone https://github.com/seantbaier/react-todo-list.git
or download the zip.
2. Make sure you’re in the todo-list-starter-files directory you
just created.
$ -cd todo-list-starter-files
$ npm install or yarn
$ npm start or yarn start

Now one last step before we dive into the code and that is to install React Developer Tools which you can grab here. Once you have this installed, open chrome dev tools and you should see a tab labeled “React.” This is where you can inspect your React components and it makes debugging a lot easier.
Virtual DOM
React Components
Function Components (stateless)
const MyComponent = (props) => {
return (
<elementOrComponent />
);
}
Class Components (stateful)
class MyComponent extends Component {
render() {
return (
<elementOrComponent />
);
}
}
todo-list-starter-files/
node_modules/
public/
favicon.ico
index.html
manifest.json
src/
components/
App.js
images/
styles/
App.test.js
index.css
pacakge.json
README.md
yarn.lock
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div className="wrapper">
<p>Let's make a todo list with React!</p>
</div>
);
}
render() {
return (
<div className="wrapper">
<form className="todoInput">
<input
className="input"
type="text"
value={this.state.pendingItem}
placeholder="Add an item"
/>
<button type="submit" name="submit" value="submit">
add
</button>
</form>
<div>{this.state.pendingItem}</div>
</div>
);
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
pendingItem: ""
};
}
...
}


handleItemInput = e => {
this.setState({
pendingItem: e.target.value
});
}
<input
className="input"
type="text"
onChange={this.handleItemInput}
value={this.state.pendingItem}
placeholder="Add an item"
/>
import React from "react";
const InputForm = props => {
return (
<form className="todoInput">
<input
className="input"
type="text"
onChange={props.handleItemInput}
value={props.pendingItem}
placeholder="Add an item"
/>
<button type="submit" name="submit" value="submit">
add
</button>
</form>
);
};
export default InputForm;
import React, { Component } from "react";
import "../styles/reset.css";
import "../styles/App.css";
import InputForm from './InputForm';
class App extends Component {
constructor(props) {
super(props);
this.state = {
pendingItem: ""
};
}
handleItemInput = e => {
this.setState({
pendingItem: e.target.value
});
}
render() {
return (
<div className="wrapper">
<InputForm
className="input"
type="text"
handleItemInput={this.handleItemInput}
value={this.state.pendingItem}
placeholder="Add an item"
/>
</div>
);
}
}
export default App;
Now on our form, we can type in items but we don’t really have a list yet. Let’s add some more state! Up in our constructor, we’ll add our list in the state.
state = {
list: [],
pendingItem: ""
};
newItemSubmitHandler = e => {
e.preventDefault();
this.setState({
list: [
{
name: this.state.pendingItem,
},
...this.state.list
],
pendingItem: ""
});
};
return (
<form
onSubmit={props.newItemSubmitHandler}
className="todoInput">
...
</form>
);
as well as make sure we pass through to props…
render() {
return (
<div className="wrapper">
<InputForm
className="input"
type="text"
handleItemInput={this.handleItemInput}
newItemSubmitHandler={this.newItemSubmitHandler}
value={this.state.pendingItem}
placeholder="Add an item"
/>
</div>
);
}
import React from "react";
const List = props => {
return (
<ul>
{props.list.map((item, index) => (
<ListItem
key={index}
item={item.name}
/>
))}
</ul>
);
};
export default List;
import List from './List';
...
render() {
return (
<div className="wrapper">
<InputForm
newItemSubmitHandler={this.newItemSubmitHandler}
handleItemInput={this.handleItemInput}
pendingItem={this.state.pendingItem}
/>
<List list={this.state.list} />
</div>
);
}
ListItem Component:
import React from "react";
const ListItem = props => {
return (
<li>
{props.item}
</li>
);
};
export default ListItem;
import ListItem from "./ListItem";

One last thing to do before we wrap up and that’s to remove our list items if we don’t want them. So let’s write another handler in App.js to update the list state when an item is removed.
handleRemove = index => {
const newState = this.state.list.filter(item => {
this.state.list.indexOf(item) !== index
});
this.setState({
list: newState
});
};
Now there are a couple extra steps here in order to make sure we remove the correct list item from our array when we click the delete button. First, we’re creating a new copy of the list by using Javascript’s filter method. This creates a new array from the list state with only the items we want to keep on our list.
Then we’re updating state and passing in the new list. As you can see we need the onClick handler to pass in an index as a parameter so let’s take care of that next.
const List = props => {
return (
<ul>
{props.list.map((item, index) => (
<ListItem
key={index}
itemIndex={index}
handleRemove={props.handleRemove}
/>
))}
</ul>
);
};
Don’t forget to pass ‘this.handleRemove’ into the List component first and then add the ‘itemIndex’ prop onto the ListItem component in the map method.
Then finally add the onClick event handler onto the button in the ListItem component. In order to pass in our index to the event handler, we’re going to use an anonymous function. This prevents the function from firing when the code is first executed and will only fire when it’s clicked on.
const ListItem = props => {
return (
<li>
{props.item}
<button className="action" onClick={
() => {props.handleRemove(props.itemIndex)}
}>
x
</button>
</li>
);
};
Aaaandd finished! I know that was a little long-winded but hopefully, you enjoyed React as much as I do. These steps are one of many ways to do this as usual when it comes to coding so I’d love to hear any alternate takes on the todo list!