How to Build a Todo App Using React, Redux, and Immutable.js
The way React uses components and a one-way data flow makes it ideal for describing the structure of user interfaces. However, its tools for working with state are kept deliberately simple — to help remind us that React is just the View in the traditional Model-View-Controller architecture.
There’s nothing to stop us from building large applications with just React, but we would quickly discover that to keep our code simple, we’d need to manage our state elsewhere.
Whilst there’s no official solution for dealing with application state, there are some libraries that align particularly well with React’s paradigm. In this post, we’ll pair React with two such libraries and use them to build a simple application.
Redux
Redux is a tiny library that acts as a container for our application state, by combining ideas from Flux and Elm. We can use Redux to manage any kind of application state, providing we stick to the following guidelines:
- our state is kept in a single store
- changes come from actions and not mutations
At the core of a Redux store is a function that takes the current application state and an action and combines them to create a new application state. We call this function a reducer.
Our React components will be responsible for sending actions to our store, and in turn our store will tell the components when they need to re-render.
ImmutableJS
Because Redux doesn’t allow us to mutate the application state, it can be helpful to enforce this by modeling application state with immutable data structures.
ImmutableJS offers us a number of immutable data structures with mutative interfaces, and they’re implemented in an efficient way, inspired by the implementations in Clojure and Scala.
Demo
We’re going to use React with Redux and ImmutableJS to build a simple todo list that allows us to add todos and toggle them between complete and incomplete.
See the Pen React, Redux & Immutable Todo by SitePoint (@SitePoint) on CodePen.
The code is available in a repository on GitHub.
Setup
We’ll get started by creating a project folder and initializing a package.json
file with npm init
. Then we’ll install the dependencies we’re going to need.
npm install --save react react-dom redux react-redux immutable
npm install --save-dev webpack babel-core babel-loader babel-preset-es2015 babel-preset-react
We’ll be using JSX and ES2015, so we’ll compile our code with Babel, and we’re going to do this as part of the module bundling process with Webpack.
First, we’ll create our Webpack configuration in webpack.config.js
:
module.exports = {
entry: './src/app.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: { presets: [ 'es2015', 'react' ] }
}
]
}
};
Finally, we’ll extend our package.json
by adding an npm script to compile our code with source maps:
"script": {
"build": "webpack --debug"
}
We’ll need to run npm run build
each time we want to compile our code.
React and Components
Before we implement any components, it can be helpful to create some dummy data. This helps us get a feel for what we’re going to need our components to render:
const dummyTodos = [
{ id: 0, isDone: true, text: 'make components' },
{ id: 1, isDone: false, text: 'design actions' },
{ id: 2, isDone: false, text: 'implement reducer' },
{ id: 3, isDone: false, text: 'connect components' }
];
For this application, we’re only going to need two React components, <Todo />
and <TodoList />
.
// src/components.js
import React from 'react';
export function Todo(props) {
const { todo } = props;
if(todo.isDone) {
return <strike>{todo.text}</strike>;
} else {
return <span>{todo.text}</span>;
}
}
export function TodoList(props) {
const { todos } = props;
return (
<div className='todo'>
<input type='text' placeholder='Add todo' />
<ul className='todo__list'>
{todos.map(t => (
<li key={t.id} className='todo__item'>
<Todo todo={t} />
</li>
))}
</ul>
</div>
);
}
At this point, we can test these components by creating an index.html
file in the project folder and populating it with the following markup. (You can find a simple stylesheet on GitHub):
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<title>Immutable Todo</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
We’ll also need an application entry point at src/app.js
.
// src/app.js
import React from 'react';
import { render } from 'react-dom';
import { TodoList } from './components';
const dummyTodos = [
{ id: 0, isDone: true, text: 'make components' },
{ id: 1, isDone: false, text: 'design actions' },
{ id: 2, isDone: false, text: 'implement reducer' },
{ id: 3, isDone: false, text: 'connect components' }
];
render(
<TodoList todos={dummyTodos} />,
document.getElementById('app')
);
Compile the code with npm run build
, then navigate your browser to the index.html
file and make sure that it’s working.
Continue reading %How to Build a Todo App Using React, Redux, and Immutable.js%
LEAVE A REPLY
You must be logged in to post a comment.