...

/

Combining the Puzzle Pieces

Combining the Puzzle Pieces

Let's now look at a working to-do list application that uses the concepts learned in the previous lessons.

To-do list app example

We now know how to use the connect() method and why we need a Provider. Let’s look at a more detailed and complete example that outlines a totally functional to-do list app. It allows us to add new to-do items, mark them as complete or not, and allows us to remove them if we want:

import React, { useState } from 'react';
import { connect } from 'react-redux';
import { addTodo, removeTodo, changeStatus } from './store/todos/actions';

const TodoList = (props) => {
    const [todoText, setTodoText] = useState('');

    return (
        <div>
            <p>{props.todos.length} Todos.</p>
            <ul>
                {props.todos.map((todo) => (
                    <li key={todo.id}>
                        <button
                            type="button"
                            onClick={() => {
                                props.removeTodo(todo.id);
                            }}
                        >
                            remove
                        </button>
                        <label
                            style={{ textDecoration: todo.done ? 'line-through' : 'none' }}
                        >
                            <input
                                type="checkbox"
                                name={todo.id}
                                checked={Boolean(todo.done)}
                                onChange={(e) => {
                                    const { name, checked } = e.target;
                                    props.changeStatus(name, checked);
                                }}
                            />
                            {todo.text}
                        </label>
                    </li>
                ))}
            </ul>
            <input onChange={(e) => setTodoText(e.target.value)} value={todoText} />
            <button
                type="button"
                onClick={() => {
                    props.addTodo(todoText);
                    setTodoText('');
                }}
            >
                add
            </button>
        </div>
    );
};

const mapStateToProps = (state) => ({
    todos: state.todos,
});

const mapDispatchToProps = {
    addTodo,
    removeTodo,
    changeStatus,
};

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(TodoList);

We’ve defined the todosReducer as well as addTodo, removeTodo, and changeStatus actions. To aid readability, both reducers and actions have been extracted into their own files within the ./store/todos directory.

Note: There’s always heated debate about how folders and files should be structured within an application. Some find a separation by the domain (for ...