Готовы ли вы проверить свои знания 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 творческих ресурсов. Создавайте с помощью уникальных шрифтов, фотографий, графики и шаблонов и быстрее выполняйте лучшие проекты.