В сегодняшней части перевода учебного курса по React мы продолжим работу над Todo-приложением и поговорим о том, как в React обрабатывают события.
→ Часть 1: обзор курса, причины популярности React, ReactDOM и JSX
→ Часть 2: функциональные компоненты
→ Часть 3: файлы компонентов, структура проектов
→ Часть 4: родительские и дочерние компоненты
→ Часть 5: начало работы над TODO-приложением, основы стилизации
→ Часть 6: о некоторых особенностях курса, JSX и JavaScript
→ Часть 7: встроенные стили
→ Часть 8: продолжение работы над TODO-приложением, знакомство со свойствами компонентов
→ Часть 9: свойства компонентов
→ Часть 10: практикум по работе со свойствами компонентов и стилизации
→ Часть 11: динамическое формирование разметки и метод массивов map
→ Часть 12: практикум, третий этап работы над TODO-приложением
→ Часть 13: компоненты, основанные на классах
→ Часть 14: практикум по компонентам, основанным на классах, состояние компонентов
→ Часть 15: практикумы по работе с состоянием компонентов
→ Часть 16: четвёртый этап работы над TODO-приложением, обработка событий
Занятие 29. Практикум. TODO-приложение. Этап №4
→ Оригинал
▍Задание
В прошлый раз мы загружали список дел для приложения из JSON-файла, а потом, проходясь по полученному массиву, формировали, с помощью метода map()
, набор компонентов. Нам хотелось бы модифицировать эти данные. А это мы сможем сделать только в том случае, если предварительно загрузим их в состояние компонента.
Сегодняшнее задание заключается в том, чтобы вы преобразовали компонент App
в компонент с состоянием и загрузили бы импортированные данные о делах в состояние этого компонента.
▍Решение
Вспомним уже имеющийся в нашем проекте код компонента App
:
import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"
function App() {
const todoItems = todosData.map(item => <TodoItem key={item.id} item={item}/>)
return (
<div className="todo-list">
{todoItems}
</div>
)
}
export default App
Для того чтобы получить возможность модифицировать данные из списка дел нам нужно чтобы то, что сейчас хранится в todosData
, было бы помещено в состояние компонента App
.
Решая эту задачу, мы сначала должны преобразовать функциональный компонент App
в компонент, основанный на классе. Потом нам нужно загрузить данные из todosData
в состояние и, формируя список компонентов TodoItem
, обходить уже не массив todosData
, а массив с такими же данными, хранящийся в состоянии. Вот как это будет выглядеть:
import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"
class App extends React.Component {
constructor() {
super()
this.state = {
todos: todosData
}
}
render() {
const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item}/>)
return (
<div className="todo-list">
{todoItems}
</div>
)
}
}
export default App
Надо отметить, что после всех этих преобразований внешний вид приложения не изменился, но выполнив их, мы подготовили его к дальнейшей работе над ним.
Занятие 30. Обработка событий в React
→ Оригинал
Обработка событий — это то, что является движущей силой веб-приложений, и то, что отличает их от простых статических веб-сайтов. Обработка событий в React устроена довольно просто, она очень похожа на то, как события обрабатываются в обычном HTML. Так, например, в React имеются обработчики событий onClick
и onSubmit
, которые сходны с аналогичными механизмами HTML, представленными в виде onclick
и onsubmit
, не только в плане имён (в React, правда, их имена формируются с использованием верблюжьего стиля), но и в том, как именно с ними работают.
Здесь мы будем рассматривать примеры, экспериментируя со стандартным приложением, создаваемым средствами create-react-app
, файл компонента App
которого содержит следующий код:
import React from "react"
function App() {
return (
<div>
<img src="https://www.fillmurray.com/200/100"/>
<br />
<br />
<button>Click me</button>
</div>
)
}
export default App
Вот как выглядит наше приложение в браузере.
Страница приложения в браузере
Прежде чем мы сможем серьёзно говорить о модификации состояния компонентов с помощью метода setState()
, нам нужно разобраться с событиями и с обработкой событий в React. Механизмы обработки событий позволяют пользователю приложения взаимодействовать с ним. Приложение же может реагировать, например, на события click
или hover
, выполняя при возникновении этих событий некие действия.
Обработка событий в React, на самом деле, устроена довольно просто. Если вам знакомы стандартные механизмы HTML, используемые для назначения элементам управления обработчиков событий, наподобие обработчика события onclick
, то вы сразу же увидите сходство с этими механизмами того, что предлагает нам React.
Например, для того, чтобы средствами HTML сделать так, чтобы по нажатию на некую кнопку выполнялась бы какая-то функция, можно воспользоваться такой конструкцией (при условии существования и доступности этой функции):
<button onclick="myFunction()">Click me</button>
В React, как уже было сказано, обработчики событий имеют имена, составленные по правилам верблюжьего стиля, то есть onclick
превратится здесь в onClick
. То же самое справедливо и для обработчика события onMouseOver
, и для других обработчиков. Причина подобного изменения заключается в том, что здесь используется подход к именованию сущностей, обычный для JavaScript.
Поработаем теперь с нашим кодом и сделаем так, чтобы кнопка реагировала бы на щелчки по ней. Вместо того чтобы передавать обработчику код для вызова функции в виде строки, мы передаём имя функции в фигурных скобках. Заготовка соответствующего фрагмента нашего кода будет теперь выглядеть так:
<button onClick={}>Click me</button>
Если вы взглянете на код компонента App
, который мы используем в этом примере, вы заметите, что там пока не объявлена функция, которую планируется вызывать при нажатии на кнопку. В общем-то, прямо сейчас мы вполне можем обойтись анонимной функцией, объявленной прямо в коде, описывающем кнопку. Вот как это будет выглядеть:
<button onClick={() => console.log("I was clicked!")}>Click me</button>
Теперь при нажатии на кнопку в консоль попадёт текст I was clicked!
.
Того же эффекта можно добиться, объявив самостоятельную функцию и приведя код файла компонента к следующему виду:
import React from "react"
function handleClick() {
console.log("I was clicked")
}
function App() {
return (
<div>
<img src="https://www.fillmurray.com/200/100"/>
<br />
<br />
<button onClick={handleClick}>Click me</button>
</div>
)
}
export default App
Для того чтобы ознакомиться с полным списком событий, поддерживаемых React, загляните на эту страницу документации.
Теперь попытайтесь оснастить наше приложение новой возможностью. А именно — сделайте так, чтобы при наведении мыши на изображение в консоль выводилось бы какое-нибудь сообщение. Для этого вам нужно найти подходящее событие в документации и организовать его обработку.
На самом деле, решить эту задачу можно разными способами, мы продемонстрируем её решение, основанное на событии onMouseOver
. При возникновении этого события мы будем выводить в консоль сообщение. Вот как будет теперь выглядеть наш код:
import React from "react"
function handleClick() {
console.log("I was clicked")
}
function App() {
return (
<div>
<img onMouseOver={() => console.log("Hovered!")} src="https://www.fillmurray.com/200/100"/>
<br />
<br />
<button onClick={handleClick}>Click me</button>
</div>
)
}
export default App
Обработка событий даёт в руки программиста огромные возможности, которые, конечно же, не ограничиваются выводом сообщений в консоль. В дальнейшем мы поговорим о том, как обработка событий, совмещённая с возможностями по изменению состояния компонентов, позволит нашим приложениям решать возлагаемые на них задачи.
Как обычно — рекомендуем уделить некоторое время на то, чтобы поэкспериментировать с тем, что вы сегодня узнали.
Итоги
Сегодня вы выполнили небольшую практическую работу, которая заложила фундамент серьёзных изменений Todo-приложения, и ознакомились с механизмами обработки событий в React. В следующий раз вам будет предложен ещё один практикум и будет представлена новая тема.
Уважаемые читатели! Если вы, ознакомившись с методикой обработки событий в React, поэкспериментировали с тем, что узнали, просим об этом рассказать.
Автор: ru_vds