Готовы ли вы проверить свои знания React? В этом видео из моего курса « Современные веб-приложения с React и Redux» вам будет предложено создать базовое приложение со списком дел в React. В частности, вам нужно будет передать данные в дочерний компонент, где они будут обновлены и отправлены обратно в родительский компонент.
Если вы не уверены, как это сделать, не беспокойтесь — вы можете перейти к решению. Я подробно рассмотрю весь процесс, чтобы показать, как это делается!
Задача: создать список дел в React
Соревнование
В этом задании вы создадите базовое приложение для списка дел в React.
У нас уже есть два компонента: компонент TodoItem
компонент TodoItem
.
Компонент TodoList
просто имеет список TodoList
в своем состоянии, и у каждого есть text
свойство и свойство done
. Затем мы можем отобразить наш список дел в компоненте TodoItem
.
Затем в компоненте TodoItem
мы просто отображаем элемент списка с полем ввода, которое имеет значение. Если этот элемент списка дел выполнен, то значение недоступно для редактирования — оно доступно только для чтения. Затем у нас есть кнопка, которую мы можем использовать, чтобы «Завершить» или «Завершить» задачу.
Прямо сейчас, это хорошо TodoList
на правой стороне, но мы не можем на самом деле изменить эти вещи в состоянии нашего компонента TodoList
. Поэтому, если я попытаюсь внести изменения в эти элементы ввода, ничего не произойдет. Если я нажму « Готово» , текст на кнопке не изменится, как должен. И я все еще могу выбрать текст в полях ввода и, если бы я мог на самом деле вносить изменения, он был бы редактируемым
Все это должно быть правильно подключено. И это ваш вызов! Вот CodePen со всем исходным кодом для работы с вами.
Раздень ручку и постарайся найти собственное решение! Или продолжайте читать, и я проведу вас через это ниже.
Решение
Начните с разветвления исходного CodePen и присвоения ему другого имени, например, добавив «МОЕ РЕШЕНИЕ».
У нас есть несколько разных вещей, которые нам нужно сделать здесь. Во-первых, внутри нашего компонента TodoItem
мы должны иметь возможность вносить изменения в эти данные. Это означает, что у нас должен быть обработчик onChange
для кнопки и обработчик onChange
для элемента ввода.
Но тогда нам нужен способ передать эти изменения обратно в родительский компонент TodoList
. Это означает, что TodoList
должен передать функцию в TodoItem
, чтобы он мог вызывать эту функцию.
Создание функции updateTodo
Поэтому мы начнем с добавления функции 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
.
Теперь, если вы нажмете « Готово» , вы увидите, что кнопка изменится на « Незакончено» , и это потому, что todo.done
теперь имеет значение true, а не false. Кроме того, текст «мыть пол» теперь немного затенен и больше не редактируется. Если я нажимаю « Неокончено» , он снова переключается на «Готово», и текстовое поле снова редактируется
Делаем текст редактируемым
Наш следующий шаг — сделать текст редактируемым, добавив обработчик onChange
.
В строке input
мы добавим onChange={this.handleChange}
. И тогда нам нужно написать handleChange
.
Мы начнем с создания newTodo
и копирования всех свойств из this.props.todo
, а затем handleChange
передаст объект нашего события. Мы собираемся установить text
равным e.target.value
. И затем под этим мы сделаем this.props.updateTodo
и передадим его newTodo
.
Так что теперь, если мы изменим текст, он работает просто отлично. Теперь мы можем сказать, купить яйца вместо молока, и мы можем сказать, мыть машину вместо пола. Итак, теперь мы успешно вносим изменения в объект в дочернем компоненте и передаем эти изменения обратно в родительский компонент, где они могут быть сохранены.
Упрощение кода
Так что теперь это работает так, как мы хотели, но есть еще одна вещь, которую я хочу сделать. Вы заметите, что функция handleChange
функция handleClick
имеют много похожего кода. У меня часто были такие дочерние компоненты, где мы хотим каким-то образом обновить объект, а затем передать его родителю, и вы обнаружите, что для этого используется общий шаблон, использующий Object.assign
таким образом.
Итак, что мы собираемся сделать, чтобы привести в порядок вещи, это создать новую функцию с именем sendDelta
. В этом случае дельта — это просто термин для обозначения того, что нужно изменить между этим делом и новым делом, которое нам нужно. Итак, что мы можем здесь сделать, это передать нашу delta
или наш объект только для свойств, которые нужно изменить, в sendDelta
.
Затем мы просто копируем код из handleClick
и вставляем его в sendDelta
. delta
— это, по сути, последний аргумент, который мы передали в Object.assign
, поэтому мы можем заменить код, выделенный ниже, на delta
, а затем просто отправить его.
Так что теперь в handleClick
и handleChange
мы можем просто заменить большую часть кода this.sendDelta
, как показано ниже. Как вы можете видеть, это намного более кратко.
Так что это решение! Для получения полного исходного кода вы можете обратиться к решению CodePen, показанному ниже:
Конечно, вы могли придумать другое решение. Если это так, это здорово. В любом случае, теперь мы успешно создали дочерний компонент, который может изменять свои данные, а затем отправлять эти изменения обратно для сохранения его родительскому компоненту.
Смотреть полный курс
В полном курсе « Современные веб-приложения с React и Redux» вы узнаете, как использовать React и Redux для создания полноценного веб-приложения. Вы начнете с самой простой архитектуры и постепенно создадите приложение, функция за функцией. К концу вы создадите полноценное приложение для изучения карточек с интервальным повторением, а также узнаете много нового о React и Redux, а также оттачиваете свои навыки в ES6 (ECMAScript 2015).
Вы можете пройти этот курс сразу же, подписавшись на Envato Elements . За небольшую ежемесячную плату вы получаете доступ не только к этому курсу, но и к нашей растущей библиотеке из более чем 1000 видеокурсов и ведущих в отрасли электронных книг по Envato Tuts +.
Кроме того, теперь вы получаете неограниченное количество скачиваний из огромной библиотеки Envato Elements из более чем 460 000 творческих ресурсов. Создавайте с помощью уникальных шрифтов, фотографий, графики и шаблонов и быстрее выполняйте лучшие проекты.