Статьи

Задача: создать список дел в React

Готовы ли вы проверить свои знания React? В этом видео из моего курса « Современные веб-приложения с React и Redux» вам будет предложено создать базовое приложение со списком дел в React. В частности, вам нужно будет передать данные в дочерний компонент, где они будут обновлены и отправлены обратно в родительский компонент.

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

В этом задании вы создадите базовое приложение для списка дел в React.

У нас уже есть два компонента: компонент TodoItem компонент TodoItem .

Компонент TodoList просто имеет список TodoList в своем состоянии, и у каждого есть text свойство и свойство done . Затем мы можем отобразить наш список дел в компоненте TodoItem .

Компонент TodoList

Затем в компоненте TodoItem мы просто отображаем элемент списка с полем ввода, которое имеет значение. Если этот элемент списка дел выполнен, то значение недоступно для редактирования — оно доступно только для чтения. Затем у нас есть кнопка, которую мы можем использовать, чтобы «Завершить» или «Завершить» задачу.

Компонент TodoItem

Прямо сейчас, это хорошо TodoList на правой стороне, но мы не можем на самом деле изменить эти вещи в состоянии нашего компонента TodoList . Поэтому, если я попытаюсь внести изменения в эти элементы ввода, ничего не произойдет. Если я нажму « Готово» , текст на кнопке не изменится, как должен. И я все еще могу выбрать текст в полях ввода и, если бы я мог на самом деле вносить изменения, он был бы редактируемым

Все это должно быть правильно подключено. И это ваш вызов! Вот CodePen со всем исходным кодом для работы с вами.

Раздень ручку и постарайся найти собственное решение! Или продолжайте читать, и я проведу вас через это ниже.

Начните с разветвления исходного CodePen и присвоения ему другого имени, например, добавив «МОЕ РЕШЕНИЕ».

У нас есть несколько разных вещей, которые нам нужно сделать здесь. Во-первых, внутри нашего компонента TodoItem мы должны иметь возможность вносить изменения в эти данные. Это означает, что у нас должен быть обработчик onChange для кнопки и обработчик onChange для элемента ввода.

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

Поэтому мы начнем с добавления функции updateTodo в TodoList с фиктивным текстом, который мы обновим позже. И теперь, когда мы создали updateTodo , мы можем использовать его в TodoItem .

Так как это может работать? Ну что ж, начнем с кнопки. Мы добавим обработчик this.handleClick и добавим this.handleClick .

Код нажатия кнопки

Итак, теперь нам нужно написать нашу функцию handleClick . Функция handleClick собирается внести изменения в свойство todo которое было передано в TodoItem .

Когда это щелкнуло, мы хотим полностью изменить значение done . Так что, если оно ложно, переключите его на true, и если это правда, переключите его на false. И затем, конечно, мы хотим передать вновь обновленный объект todo через функцию updateTodo .

Мы можем получить наш newTodo , выполнив Object.assign , чтобы не изменять данные. И мы скопируем все свойства в нашу существующую задачу, которая на самом деле это this.props.todo .

Но затем мы хотим убедиться, что мы перезаписываем свойство done , которое должно быть обратным или отрицательным для this.props.todo.done .

Код для новой задачи

Так что это наш newTodo . И тогда мы можем сделать this.props.updateTodo , и мы передадим его нашему newTodo .

Нажмите обрабатывать полный код

ОК, так что это обработка клика. Теперь давайте спустимся и напишем наш updateTodo , чтобы мы могли увидеть это в действии. Прямо сейчас, если я нажму « Готово» , вы увидите, что наш новый объект дел выводится на печать, где для параметра «выполнено» задано значение «истина», но мы пока не видим этого в пользовательском интерфейсе. Это потому, что сейчас нам нужно сохранить эту новую todo обратно в наше состояние todos .

Консоль, показывающая задачу, выполнена, но не отражена в пользовательском интерфейсе

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

Теперь я собираюсь установить состояние так, как вы, возможно, не видели раньше. Мы собираемся передать функцию для установки состояния вместо передачи объекта. На самом деле это считается хорошей практикой в ​​React и, возможно, может быть единственным способом установить состояние в будущем. Функция, которую вы передаете setState , получит текущее состояние в качестве параметра. Таким образом, мы можем получить это состояние в качестве параметра этой функции, а затем мы возвращаем наше новое состояние из этой функции.

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

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

Давайте возьмем наши существующие state.todos , и мы сопоставим каждую todo , и если todo.id равен newTodo.id , то мы знаем, что это объект todo который мы должны заменить. Таким образом, мы можем заменить его на newTodo , а в противном случае мы можем просто вернуть старое todo , потому что мы не собираемся его заменять.

Код для установки состояния

И тогда нам просто нужно изменить нашу функцию updateTodo для ссылки на this.updateTodo .

функция updateTodo обновлена

Теперь, если вы нажмете « Готово» , вы увидите, что кнопка изменится на « Незакончено» , и это потому, что todo.done теперь имеет значение true, а не false. Кроме того, текст «мыть пол» теперь немного затенен и больше не редактируется. Если я нажимаю « Неокончено» , он снова переключается на «Готово», и текстовое поле снова редактируется

Список задач, показывающий один выполненный элемент

Наш следующий шаг — сделать текст редактируемым, добавив обработчик onChange .

В строке input мы добавим onChange={this.handleChange} . И тогда нам нужно написать handleChange .

Мы начнем с создания newTodo и копирования всех свойств из this.props.todo , а затем handleChange передаст объект нашего события. Мы собираемся установить text равным e.target.value . И затем под этим мы сделаем this.props.updateTodo и передадим его newTodo .

код обработчика onChange

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

Так что теперь это работает так, как мы хотели, но есть еще одна вещь, которую я хочу сделать. Вы заметите, что функция handleChange функция handleClick имеют много похожего кода. У меня часто были такие дочерние компоненты, где мы хотим каким-то образом обновить объект, а затем передать его родителю, и вы обнаружите, что для этого используется общий шаблон, использующий Object.assign таким образом.

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

Затем мы просто копируем код из handleClick и вставляем его в sendDelta . delta — это, по сути, последний аргумент, который мы передали в Object.assign , поэтому мы можем заменить код, выделенный ниже, на delta , а затем просто отправить его.

функция sendDelta

Так что теперь в handleClick и handleChange мы можем просто заменить большую часть кода this.sendDelta , как показано ниже. Как вы можете видеть, это намного более кратко.

Упрощенный код

Так что это решение! Для получения полного исходного кода вы можете обратиться к решению CodePen, показанному ниже:

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

В полном курсе « Современные веб-приложения с React и Redux» вы узнаете, как использовать React и Redux для создания полноценного веб-приложения. Вы начнете с самой простой архитектуры и постепенно создадите приложение, функция за функцией. К концу вы создадите полноценное приложение для изучения карточек с интервальным повторением, а также узнаете много нового о React и Redux, а также оттачиваете свои навыки в ES6 (ECMAScript 2015).

Вы можете пройти этот курс сразу же, подписавшись на Envato Elements . За небольшую ежемесячную плату вы получаете доступ не только к этому курсу, но и к нашей растущей библиотеке из более чем 1000 видеокурсов и ведущих в отрасли электронных книг по Envato Tuts +.

Кроме того, теперь вы получаете неограниченное количество скачиваний из огромной библиотеки Envato Elements из более чем 460 000 творческих ресурсов. Создавайте с помощью уникальных шрифтов, фотографий, графики и шаблонов и быстрее выполняйте лучшие проекты.