Будущих студентов курса "React.js Developer" приглашаем записаться на бесплатный демо-урок по теме "Пишем приложение на React+Redux".
А также подготовили для вас перевод полезного материала.
Если вы только начали изучать React, для отработки основных концепций этого фреймворка можно создать простое приложение. Первое, что приходит в голову, — это приложение для составления списка дел или покупок. С него и начнем. Основные концепции React изложены в официальной документации на сайте, а в предыдущих записях моего блога можно найти ссылки на другие руководства по работе с React.
Запустите VS Code или любой другой редактор кода. Для создания React-приложения наберите в терминале команду:
npx create-react-app grocerylist
Затем смените директорию:
cd grocerylist
Запустите сервер:
npm start
Откройте в браузере адрес http://localhost:3000/, и вы увидите следующее окно:
Давайте посмотрим, какие элементы интерфейса нам нужно создать, и приступим к разработке.
1. Сначала создадим поле для ввода пункта в список.
2. Затем — кнопку для сохранения пункта.
3. Наконец, создадим список для отображения пунктов с возможностью удалять пункты и помечать их как выполненные.
Для разработки такого приложения нужно изучить работу с хуками, способы создания базовых форм, работу с массивами, объектами, стрелочными функциями, оператором расширения массива и пропсами.
Поработаем с кодом в файле App.js. Мы будем использовать функциональные компоненты и хук useState()
для определения состояния.
Создадим форму:
<form onSubmit={handleSubmit}>
<input type="text" value={item} onChange={handleChange} />
<button type="submit">ADD</button>
</form>
Вот как будет выглядеть весь наш код после создания формы:
import React, { useState } from "react";
import "./App.css"
import { v4 as uuidv4 } from "uuid";
function App() {
const [item, setItem] = useState("");
const [list, setList] = useState([]);
const handleSubmit = (e) => {
const newItem = {
id: uuidv4(),
item: item,
complete: false,
};
e.preventDefault();
if (item) {
setList([...list, newItem]);
setItem("");
}
};
const handleChange = (e) => {
setItem(e.target.value);
};
return (
<div className="App">
<h1>Grocery List</h1>
<form onSubmit={handleSubmit}>
<input type="text" value={item} onChange={handleChange} />
<button type="submit">ADD</button>
</form>
</div>
);
}
export default App;
Объясним вышенаписанный код. Мы создали переменную состояния item
, в которой хранится значение элемента списка, введенного пользователем. Затем мы создали еще одну переменную состояния list
, в которой хранится коллекция элементов списка в виде массива.
Мы создали стрелочную функцию handleChange
для изменения состояния item
каждый раз, когда пользователь вводит новое значение в форму. Мы изменяем состояние с помощью setItem
и назначаем его в качестве целевого значения. Мы создали еще одну функцию handleSubmit
для обновления массива элементов списка каждый раз, когда пользователь вводит новый пункт. У каждого пункта есть следующие свойства: уникальный id, который генерируется как UUID, item
и complete
. Свойство complete
является логическим состоянием: если ему присвоено значение true
, пункт в списке помечается как выполненный, а значение false
присваивается невыполненным пунктам.
Теперь создадим новый компонент Item.js
. Для этого напишем такой код:
import React from "react";
import "./Item.css";
const Item = ({ id, items, list, setList, complete }) => {
const remove = (id) => {
setList(list.filter((el) => el.id !== id));
};
const handleComplete = (id) => {
setList(
list.map((item) => {
if (item.id === id) {
return {
...item,
complete: !item.complete,
};
}
return item;
})
);
};
return (
<div className="item">
<p className={complete ? "complete" : ""}>{items}</p>
<img
onClick={() => handleComplete(id)}
src="https://img.icons8.com/offices/40/000000/checked-2--v2.png"
alt="complete task"
/>
<img
onClick={() => remove(id)}
src="https://img.icons8.com/color/48/000000/trash.png"
alt="Delete"
/>
</div>
);
};
export default Item;
Чтобы удалять пункты, мы будем отфильтровывать пункт, который надо удалить, сравнивая пункты по их id. После удаления пункта остальные пункты продолжат отображаться. Чтобы помечать пункты как выполненные, мы будем перебирать все элементы массива в переменной list
, сравнивать их по id и менять значение состояния complete
для соответствующего элемента. Оформите приложение по своему вкусу. Можно воспользоваться стилизованными React-компонентами, которые доступны тут.
Вот как будет выглядеть наше приложение:
Демоверсия приложения. Репозиторий на GitHub.
Что еще можно сделать:
1. Добавить локальное хранилище.
2. Добавить серверную часть на основе Firebase.
3. Добавить функции регистрации и входа.
Предложения приветствуются.
Узнать подробнее о курсе "React.js Developer".
Записаться на открытый урок "Пишем приложение на React+Redux".
nin-jin
Вредные советы какие-то.
iDm1
Так альтернативы Redux походят не на все случаи жизни. Хотя описываемый в статье пример конечно не из них.
nin-jin
На какие, например, не подходят?
MaZaAa
MobX подходит на все случаи жизни, более того, он расширяет границы этих случаев жизни значительно. Так что, какое-то у вас странное представление мягко говоря о стейт менеджерах.
iDm1
Не исключено, но становится ли тогда совет с использованием Redux прямо таки вредным?
MaZaAa
Разумеется использовать Redux уже несколько лет как вредно, так же вредно как использовать голый реакт и его средства управления состоянием, в самом начале, годах в 2014 и в 2015 да, мало было опыта у людей и тп., использовали Redux, но уже с 2016 года люди стали опытнее, умнее, начали смотреть по сторонам, а тут бац и есть такая вещь как MobX, которая кардинально меняет проблему управления состоянием приложения, как глобального, так и локального у каждого компонента сильно в лучшую сторону. Более того, автоматически решается проблема производительности связанная с иммутабильностью и лишними перерендерами, т.к. MobX про мутабильность и реактивность.
nin-jin
KnockoutJS, VueJS, $mol…
Но эти умные люди продолжают держаться за React, словно это их мать родная. Вот и получается — на примере каких технологий ты обучаешь новичка, то и заимпринтится ему в подкорку.
MaZaAa
React как view слой более чем удобный и приятный, с полной поддержкой Typescript, но только как view слой.
Управление состоянием у него ущербное, поэтому он пригоден для использования только в паре с MobX, чтобы быть реально хорошим инструментом не вызывающим отвращения.
nin-jin
О да, тонны копипасты и push семантика — это прям так удобно и эффективно. Вы — наглядная иллюстрация моих слов.
MaZaAa
Какой копипасты?
nin-jin
Я тут разбирал типичный пример: https://habr.com/ru/post/491120/#razbor-polyotov
MaZaAa
Ну вот же, у вас там всё и написано.
Причем тут копи паста? Надуманный говнокод из вашей же статьи? Ну он же просто надуманный. Те кто пишет такой говнокод реально, так это проблема в том, что они криворукие, а не в реакте.
nin-jin
При том, что для того, чтобы код выглядел как на первом скриншоте нужно писать свою jsx фабрику.
Тут я разбираю эту проблематику более подробно: https://habr.com/ru/post/461395/
MaZaAa
И в чем проблема? Написал и забыл.
nin-jin
Помимо того, что это уже будет не React, — никто это ещё не написал — все копипастят и притворяются, что проблем нет, а решения этих проблем называют говном только на том основании, что оно не похоже на jsx.