При управлении сложными состояниями в приложении Next все может быстро усложниться. Традиционные крючки, такие как использование состояния помочь с государственным управлением, но представляет проблему бурения опоры. Детализация реквизита означает передачу данных или функций через несколько компонентов.

Лучшим подходом было бы отделение логики управления состоянием от компонентов и обновление этих состояний из любого места приложения. Мы покажем вам, как использовать Context API, пока мы создаем простое приложение списка дел.

Прежде чем вы начнете свой список дел

Прежде чем вы сможете создать приложение списка дел, вам потребуется:

  • Базовые знания современные операторы JavaScript и Хук useState в React.
  • Понимание того, как деструктурировать массивы и объекты в JavaScript.
  • Узел v16.8 или более поздняя версия, установленная на вашем локальном компьютере, и знакомство с менеджеры пакетов, такие как npm или пряжа.

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

Понимание состояния приложения и управления им

instagram viewer

Состояние приложения относится к текущему состоянию приложения в данный момент времени. Это включает в себя информацию, которую приложение знает и которой управляет, например пользовательский ввод и данные, полученные из базы данных или API (интерфейс прикладного программирования).

Чтобы понять состояние приложения, рассмотрите возможные состояния простого приложения-счетчика. Они включают:

  • Состояние по умолчанию когда счетчик на нуле.
  • Повышенное состояние когда счетчик увеличивается на единицу.
  • Пониженное состояние когда счетчик уменьшается на единицу.
  • Состояние сброса когда счетчик возвращается в состояние по умолчанию.

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

В этом фрагменте показано простое приложение-счетчик в состоянии по умолчанию, которое управляет состоянием на основе действий по клику:

константа [счетчик, setCounter] = useState(0);

возвращаться (


{счетчик}</h1>

Настройка и установка

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

Клонирование стартового приложения

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

мерзавец клон -б стартер https://github.com/makeuseofcode/Next.js-CRUD-todo-app.git

Выполните следующую команду в каталоге проекта, чтобы установить зависимости и запустить сервер разработки:

пряжа && пряжа dev

Или:

npm i && npm запустить dev

Если все прошло хорошо, пользовательский интерфейс должен отобразиться в вашем браузере:

Реализация логики

Context API предоставляет способ управления и обмена данными о состоянии между компонентами без необходимости ручного детализации свойств.

Шаг 1: Создайте и экспортируйте контекст

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

Импортировать создатьконтекст функцию от реагировать библиотеку и вызвать ее, сохранив результат в переменной:

Импортировать {создатьконтекст} от"реагировать";
константа TodoContext = createContext();

Далее создайте пользовательский использованиеTodoContext хук, который возвращает TodoContext в пригодной для использования форме.

экспортконстанта использоватьTodoContext = () => использоватьконтекст (TodoContext);

Шаг 2. Создание состояний и управление ими

Для выполнения действий приложения CRUD (создание, чтение, обновление, удаление) вам необходимо создать состояния и управлять ими с помощью Провайдер компонент.

константа TodoContextProvider = ({ дети }) => {
константа [задача, setTask] = useState("");
константа [задачи, setTasks] = useState([]);
возвращаться<TodoContext. Провайдерценить={{}}>{дети}TodoContext. Провайдер>;
};

экспортпо умолчанию TodoContextProvider;

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

константа обработатьTodoInput = (вход) => setTask (ввод);

Добавить создать задачу функция, которая запускается, когда пользователь отправляет задачу. Эта функция обновляет задания состояние и присваивает новой задаче случайный идентификатор.

константа создатьзадачу = (е) => {
e.preventDefault();

установитьЗадачи([
{
идентификатор: Математика.trunc(Математика.случайный() * 1000 + 1),
задача,
},
...задания,
]);
};

Создать updateTask функция, отображающая через задания list и обновляет задачу, идентификатор которой совпадает с идентификатором выбранной задачи.

константа задача обновления = (идентификатор, обновить текст) =>
setTasks(tasks.map((т) => (идентификатор t.id? { ...т, задача:updateText }:t)));

Создать удалить задачу функция, которая обновляет задания список, чтобы он включал все задачи, идентификатор которых не соответствует заданному параметру.

константа удалитьЗадание = (идентификатор) => setTasks (задачи.фильтр((т) => t.id !== id));

Шаг 3: Добавьте состояния и обработчики к провайдеру

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

возвращаться (
значение = {{
задача,
задания,
ручкаTodoInput,
создатьзадачу,
обновлениеЗадача,
удалитьЗадание,
}}
>
{дети}
</TodoContext.Provider>
);

Шаг 4: Охват контекста

Провайдер который вы создали, должен обернуть компонент верхнего уровня, чтобы сделать контекст доступным для всего приложения. Для этого отредактируйте источник/приложение/page.jsx и завернуть Todos компонент с TodoContextProvider компонент:


;
</TodoContextProvider>;

Шаг 5: Используйте контекст в компонентах

Отредактируйте свой источник/приложение/компоненты/Todos.jsx файл и деструктурировать задачи, задача, обработатьTodoInput, и создать задачу через звонок в использованиеTodoContext функция.

константа { задача, задачи, handleTodoInput, createTask } = useTodoContext();

Теперь обновите элемент формы, чтобы он обрабатывал событие отправки и изменения в основном поле ввода:

создатьЗадание (д)}>
"todo-ввод" тип="текст" заполнитель ="Введите задачу" требуемое значение={задача} onChange={(e) => handleTodoInput (e.target.value)} />
"отправить-дело" тип="представлять на рассмотрение" значение ="Добавить задачу" />
</form>

Шаг 6: Рендеринг задач в пользовательском интерфейсе

Теперь вы можете использовать приложение для создания и добавления задачи в задания список. Чтобы обновить дисплей, вам нужно сопоставить существующие задания и отображать их в пользовательском интерфейсе. Сначала создайте источник/приложение/компоненты/Todo.jsx компонент для хранения одного элемента списка дел.

В рамках источник/приложение/компоненты/Todo.jsx компонента, отредактируйте или удалите задачу, вызвав updateTask и удалить задачу функции, которые мы создали в источник/приложение/контекст/todo.context.jsx файл.

Импортировать Реагировать, {useState} от"реагировать";
Импортировать { useTodoContext } от"../контекст/todo.контекст";

константа Сделать = ({ задача }) => {
константа { updateTask, deleteTask } = useTodoContext();

// состояние isEdit отслеживает, когда задача находится в режиме редактирования
константа [isEdit, setIsEdit] = useState(ЛОЖЬ);

возвращаться (

"todo-обертка">


{Редактировать? ( <входтип="текст"ценить={задача.задача}
onChange={(e) => updateTask (task.id, e.target.value)} /> ) :
(<йclassName="задача">{задача.задача}й> )}
"действия">

экспортпо умолчанию Делать;

Чтобы сделать источник/приложение/компоненты/Todo.jsx компонент для каждого задача, зайти в источник/приложение/компоненты/Todos.jsx файл и условно отображать через задания сразу после заголовок закрывающий тег.

{задания && (

{задачи.карта((задача, я) => ( <Делатьключ={я}задача={задача} /> ))}
</main>
)}

Протестируйте свое приложение в браузере и убедитесь, что оно дает ожидаемый результат.

Сохранение задач в локальном хранилище

В настоящее время при обновлении страницы задачи сбрасываются, а созданные вами отбрасываются. Один из способов решить эту проблему — сохранить задачи в локальном хранилище браузера.

API веб-хранилища представляет собой усовершенствование хранилища файлов cookie с функциями, которые улучшают работу как пользователей, так и разработчиков.