Создание приложения-планировщика в React с Easy Peasy и Ant Design

Приложения-планировщики повсеместно входят в нашу жизнь. Они помогают держать во внимании намеченные задачи и выполнять дела в течение дня. 

Данное руководство научит вас создавать веб-приложение для составления списка дел с помощью React. Для хранения и обмена данными между несколькими компонентами воспользуемся библиотекой управления состояниями Easy Peasy. Кроме того, для придания UI более привлекательного вида проект будет задействовать компоненты из библиотеки Ant Design

По итогам работы мы получим следующий результат: 

Приступаем! 

Начальный этап 

Создание проекта 

Создаем пустой репозиторий React, выполняя команду терминала: 

npx create-react-app todo-easy-peasy

Установка модулей 

Требуемые зависимости для проекта: 

  • easy-peasy позволяет хранить пользовательские данные и предоставлять их для работы разным частям приложения. 
  • antd обеспечивает возможность применения компонентов из пакета Ant Design. 
  • nanoid предназначен для присваивания элементам ID полей.

Для установки пакетов выполняем bash-команду: 

npm i easy-peasy antd nanoid

Структура каталога проекта 

На данном этапе создадим в проекте несколько каталогов, тем самым структурируя код и добиваясь его чистоты. 

Размещаем директорию src в репозитории и создаем в ней следующие каталоги: 

  • components предназначен для хранения пользовательских компонентов; 
  • store станет местом для хранилища Easy Peasy, в котором будут находиться состояния и действия.  

Далее выполняем нижеуказанную bash-инструкцию: 

cd src #переходим в директорию 
mkdir components store

И структура проекта приобретает следующий вид: 

Создание приложения-планировщика 

Компонент элемента списка дел 

В данном разделе напишем код пользовательского компонента, который будет представлять каждый элемент в списке дел. 

В каталоге components создаем файл с именем TodoItem.js, в котором прописываем следующий код: 

import { List, Button, Typography } from "antd";
const { Text } = Typography;

export default function TodoItem({ todo }) {
return (
<>
<List.Item>
<Text> {todo.task} </Text>
</List.Item>
</>
);
}
  • Строка 4. Модуль TodoItem принимает свойство todo, которое соответствует элементу в списке. 
  • Строка 8. Отображает поле task объекта todo

Создание хранилища 

В каталоге store создаем файл todoStore.js. Он будет содержать переменные состояния и их действия. 

В store/todoStore.js пишем такой фрагмент кода: 

import { createStore } from "easy-peasy";

const todoModel = {
todos: [{ id: 1, task: "Pick up eggs" }]
};
const store = {
todoModel
};
export default createStore(store);
  • Строка 4. Определяем состояние todos
  • Строка 9. Создаем и экспортируем хранилище, тем самым связывая его с проектом. 

Отображение элементов списка дел 

Хранилище готово  —  переходим к созданию компонента React, ответственного за отображение в списке элементов пользователя. 

В каталоге components создаем файл TodoList.js и прописываем в нем блок кода: 

import { List } from "antd";
import TodoItem from "./TodoItem";
import { useStoreState } from "easy-peasy";
export default function TodoList() {
const todos = useStoreState((state) => state.todoModel.todos);
return (
<div>
{todos && (
<List
itemLayout="horizontal"
dataSource={todos}
renderItem={(item) => <TodoItem todo={item} />}
/>
)}
</div>
);
}
  • Строка 5. Извлекаем состояние todos из хранилища. 
  • Строки 9–12. С помощью компонента List перечисляем все элементы списка дел, каждый из которых будет отображаться посредством компонента TodoItem

После этого остается лишь связать хранилище с проектом. Для этого заменяем весь код в src/App.js на указанный ниже: 

import { StoreProvider } from "easy-peasy";
import "antd/dist/antd.css";
import TodoList from "./components/TodoList";
import store from "./store/todoStore";

export default function App() {
return (
<div className="App">
<StoreProvider store={store}>
<TodoList />
</StoreProvider>
</div>
);
}
  • Обертываем компонент TodoList тегами StoreProvider. Свойство store указывает на хранилище, которое надлежит использовать. Задача выполнена  —  хранилище связано с приложением. 

Ниже представлен результат кода: 

Результат выполнения кода 

Добавление задач в список дел 

В этом разделе напишем функцию, благодаря которой пользователь сможет дополнять список дел новыми задачами. 

В store/todoStore.js находим объект todoModel и вносим свойство addTodo:

import { action } from "easy-peasy";
import { nanoid } from "nanoid";
const todoModel = {
addTodo: action((state, payload) => {
payload.id = nanoid();
state.todos.push(payload);
}),
//дальнейший код...
  • Строка 4. Создаем действие addTodo.
  • Строка 5. Присваиваем id нового элемента, используя модуль nanoid.  
  • Строка 6. В завершение добавляем новую задачу в массив todos

Далее переходим в каталог components и создаем там файл AddTodo.js. Этот компонент позволит пользователям вводить данные в хранилище. 

В components/AddTodo.js прописываем блок кода: 

import { useForm, Controller } from "react-hook-form";
import { useStoreActions } from "easy-peasy";
import { Input } from "antd";

export default function AddTodo() {
const addTodo = useStoreActions((state) => state.todoModel.addTodo);
const { handleSubmit, control, reset } = useForm();
const onSubmit = (data) => {
addTodo(data);
reset(); //empty the contents of the textbox
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="task"
control={control}
defaultValue=""
render={({ field }) => <Input autoComplete="off" {...field} />}
/>
<input type="submit" value="Add" />
</form>
);
}
  • Строка 6. Извлекаем функцию addTodo из хранилища. 
  • Строка 13. Метод onSubmit является обработчиком для данной формы. Это значит, что при отправке пользователем формы программа вызовет метод addTodo, в результате чего список пополнится новым элементом. 
  • Строки 14–19. Компонент Controller позволяет поймать пользовательский ввод. 

Теперь осталось лишь отобразить компонент AddTodo в DOM. Для этого переходим в App.js и меняем блок return таким образом: 

return (
<div className="App">
<StoreProvider store={store}>
<AddTodo />
<TodoList />
</StoreProvider>
</div>
);
  • Строка 4. Отображаем AddTodo в качестве дочернего компонента StoreProvider. Это значит, что теперь AddTodo обладает доступом к хранилищу. 

Выполняем код и получаем следующий результат: 

Удаление задач из списка дел 

В этом разделе займемся написанием кода, который позволяет пользователям удалять элементы из списка 

Для этого переходим в store/todoStore.js и вносим данный фрагмент кода: 

const todoModel = { //Этот метод станет частью хранилища. 
removeTodo: action((state, id) => {
state.todos = state.todos.filter((todo) => todo.id !== id);
}),
//дальнейший код...
  • Строка 2. Объявляем действие removeTodo
  • Строка 3. Проводим поиск нужного элемента массива и удаляем его. 

Теперь проверяем все в действии! 

На завершающем этапе переходим в components/TodoItem.js и добавляем фрагмент кода: 

import {Button} from "antd"

const removeTodo = useStoreActions((state) => state.todoModel.removeTodo);
return (
<>
<List.Item
actions={[<Button type="primary" danger onClick={() => removeTodo(todo.id)}> Delete</Button>]}
>
<Text> {todo.task} </Text>
</List.Item>
</>
);
//дальнейший код..
  • Строка 3. Получаем метод removeTodo из хранилища. 
  • Строка 7. Свойство actions принимает массив компонентов, позволяющий взаимодействовать с элементом списка. Здесь мы передаем элемент Button. При нажатии пользователем на кнопку приложение вызывает метод removeTodo, что приводит к удалению требуемого элемента из списка. 

Полученный результат:

Отображение количества элементов посредством вычисляемых свойств 

Если вкратце, то вычисляемые свойства  —  это состояния, полученные из других состояний. В этом проекте мы воспользуемся ими для отображения количества задач в списке дел. 

Переходим в store/todoStore.js, находим там объект todoModel и добавляем свойство numberOfItems:

import { computed } from "easy-peasy";

const todoModel = { //numberOfItems станет частью хранилища.
numberOfItems: computed((state) => state.todos.length),
//дальнейший код...
  • Строка 4. Состояние numberOfItems будет получено из массива todos. Сохраняем длину состояния todos и присваиваем ее numberOfItems .

Теперь применим это состояние! Для этого переходим в components/TodoList.js и дополняем его указанным фрагментом кода: 

const { Title } = Typography;

const numberOfItems = useStoreState((state) => state.todoModel.numberOfItems);
return (
<div>
<Title level={3}> Number of items: {numberOfItems}</Title>
{/*Further code..*/}
</div>
);
  • Строка 3. Получаем состояние numberOfItems из хранилища. 
  • Строка 6. Отображаем значение numberOfItems в пользовательском интерфейсе. 

Результат:

Цель достигнута! 

Дополнительные ресурсы 

Репозиторий CodeSandbox для данного проекта. 

Заключение 

Из материала статьи вы узнали, как создать приложение-планировщик, используя Easy Peasy в качестве хранилища данных. Эта превосходная библиотека управления состояниями как нельзя лучше подойдет для вашего проекта. Кроме того, благодаря простоте применения Easy Peasy помогает программистам быстро запускать процесс разработки. 

Благодарим за внимание! 

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Hussain Arif: Build a To-Do App in React With Easy Peasy and Ant Design

Предыдущая статья6 упущений в курсе науки о данных
Следующая статьяВеб-разработка: основы статического сайта