Приложения-планировщики повсеместно входят в нашу жизнь. Они помогают держать во внимании намеченные задачи и выполнять дела в течение дня.
Данное руководство научит вас создавать веб-приложение для составления списка дел с помощью 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 помогает программистам быстро запускать процесс разработки.
Благодарим за внимание!
Читайте также:
- Python Django: Front End на React
- React.js за 5 минут
- Понятие о порталах в React с примерами использования
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Hussain Arif: Build a To-Do App in React With Easy Peasy and Ant Design