React (также известный как React.js или ReactJS) — это библиотека JavaScript для создания пользовательских интерфейсов. Возникший из внутреннего проекта Facebook, он изначально использовался для настройки веб-сайта Instagram и был открыт в мае 2013 года. React обладает высокой производительностью, а его декларативные и компонентные функции упрощают написание кода.С развитием сообщества React все больше и больше людей вкладывают средства в изучение и разработку React, так что React можно использовать не только для разработки веб-приложений, а также может разрабатывать настольные приложения, ТВ-приложения, VR-приложения, IoT-приложения и т. д., поэтому React также имеет функцию обучения один раз и написания в любом месте. Это руководство поможет вам быстро приступить к разработке React.Через 20-30 минут обучения вы сможете не только понять основные концепции React, но и разработать небольшое приложение со списком дел.О чем вы все еще думаете? Узнайте сейчас! Весь код в этой статье был помещен вРепозиторий GitHubсередина.
Этот учебник принадлежитМаршрут обучения фронтенд-инженера ReactЧасть, добро пожаловать в звездную волну, поощряйте нас продолжать создавать лучшие учебные пособия и продолжать обновлять ~
Hello, World
Что будем строить?
В этом руководстве мы покажем вам, как создать приложение для создания списка дел с помощью React, показав результаты финального проекта ниже:
Вы также можете увидеть результат нашей окончательной сборки здесь:Окончательные результаты. Если вы сейчас не очень хорошо понимаете код или не знакомы с синтаксисом кода, не волнуйтесь! Цель этого руководства — помочь вам понять React и его синтаксис.
Мы рекомендуем вам ознакомиться с этим списком дел, прежде чем продолжить работу с этим руководством, и вы даже можете попробовать добавить несколько дел! Вы могли заметить, что после того, как вы добавите 2 задачи, появятся разные цвета; это магия условного рендеринга в React.
Когда вы знакомы с этой задачей, вы можете закрыть ее. В этом руководстве мы начнем с шаблона кода Hello World и проведем вас через инициализацию среды разработки, чтобы вы могли приступить к созданию задачи.
Чему вы научитесь?
Вы изучите все основные концепции React, которые разделены на три части:
- Написание связанных компонентов: включая синтаксис JSX, компонент, реквизит
- Взаимодействие компонентов: включая состояние и жизненный цикл
- Рендеринг компонентов: включая списки и ключи, условный рендеринг
- Относится к DOM и HTML: включая обработку событий, формы.
Предварительные условия
Мы предполагаем, что вы знакомы с HTML и JavaScript, но даже если вы переходите с другого языка программирования, вы можете следовать этому руководству. Мы также предполагаем, что вы знакомы с некоторыми понятиями языка программирования, такими как функции, объекты, массивы и, желательно, классы.
Если вам нужно освежить в памяти JavaScript, мы рекомендуем прочитатьэто руководство. Вы могли заметить, что мы используем некоторые функции ES6 — последнюю версию JavaScript. В этом уроке мы будем использоватьarrow functions,classes,а такжеconst. вы можете использоватьBabel REPLчтобы проверить результат компиляции кода ES6.
Подготовка окружающей среды
Сначала подготовьте среду разработки Node, посетитеофициальный сайт узлаЗагрузить и установить. Откройте терминал и введите следующую команду, чтобы проверить, успешно ли установлен Node:
node -v # v10.16.0
npm -v # 6.9.0
Уведомление
Пользователям Windows необходимо открыть инструмент cmd, Mac и Linux — терминал.
Если приведенная выше команда имеет выходные данные и об ошибках не сообщается, это означает, что среда Node успешно установлена. Далее мы будем использовать скаффолдинг React —Create React App(CRA для краткости) для инициализации проекта, и это также официально рекомендуемый лучший способ инициализации проекта React.
Введите в терминал следующую команду:
npx create-react-app my-todolist
Дождитесь завершения выполнения команды, затем введите следующую команду, чтобы открыть проект:
cd my-todolist && npm start
CRA автоматически откроет проект и откроет браузер, вы должны увидеть следующие результаты:
🎉🎉🎉 Поздравляем! Вы успешно создали свое первое приложение React!
Сейчас в проекте, инициализированном CRA, много ненужного контента, и нам нужно немного почистить его, чтобы приступить к следующему обучению. Сначала в терминале нажмитеctrl + c
Закройте среду разработки, которую вы только что запустили, а затем последовательно введите в терминал следующие команды:
# 进入 src 目录
cd src
# 如果你在使用 Mac 或者 Linux:
rm -f *
# 或者,你在使用 Windows:
del *
# 然后,创建我们将学习用的 JS 文件
# 如果你在使用 Mac 或者 Linux:
touch index.js
# 或者,你在使用 Windows
type nul > index.js
# 最后,切回到项目目录文件夹下
cd ..
На этом этапе, если вы запустите в каталоге проекта терминалаnpm start
сообщит об ошибке, потому что нашindex.js
Контента пока нет, используем в терминалеctrl +c
Выключите сервер разработки, затем откройте проект в редакторе и добавьте следующий код в только что созданный файл index.js:
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
render() {
return <div>Hello, World</div>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Мы виделиindex.js
Код внутри разделен на три части.
Первый - это серия импортных пакетов, которые мы импортировалиreact
пакет с именем React, импортированныйreact-dom
пакет и назовите его ReactDOM. Все файлы, содержащие компоненты React (которые мы рассмотрим позже), должны импортировать React в начале файла.
Затем мы определяем компонент React с именем App, который наследуется от React.Component Мы объясним содержание компонента позже.
Затем мы используем метод рендеринга ReactDOM для рендеринга компонента приложения, который мы только что определили.render
Метод получает два параметра, первый параметр — это наш компонент корневого уровня React, а второй параметр получает узел DOM, что означает, что мы смонтируем приложение React под этим узлом DOM, а затем отобразим его в браузере.
Уведомление
В трех частях приведенного выше кодаЧасти 1 и 3 не будут изменены на протяжении всего обучения., при написании любого приложения React требуются обе части. Все модификации кода, связанные с нижеследующим, являются модификациями второй части кода или вставкой или удалением кода между первой частью и третьей частью.
Сохраните код, используйте его в терминалеnpm start
команда для запуска сервера разработки, теперь браузер должен отображать следующее:
Препараты готовы!
Возможно, вам не очень понятны детали приведенного выше кода, не волнуйтесь, мы быстро перенесем вас в волшебный мир React!
Синтаксис JSX
Сначала давайте взглянем на одну из гордых функций React — JSX. Это позволяет нам использовать синтаксис XML в коде JS для написания пользовательского интерфейса, чтобы мы могли в полной мере использовать мощные функции JS для работы с пользовательским интерфейсом.
в методе рендеринга компонента Reactreturn
Контент — это то, что этот компонент будет отображать. Например, наш текущий код:
render() {
return <div>Hello, World</div>;
}
здесь<div>Hello, World</div>
это кусок кода JSX, который в конечном итоге будетBabelПереведите в следующий код JS:
React.createElement(
'div',
null,
'Hello, World'
)
React.createElement()
Принимает три параметра:
- Первый параметр представляет тег элемента JSX.
- Второй параметр представляет свойство, полученное этим элементом JSX, это объект, потому что наш
div
не получает никаких свойств, поэтомуnull
. - Третий параметр представляет содержимое, обернутое элементом JSX.
React.createElement()
Будут некоторые проверки параметров, чтобы убедиться, что код, который вы пишете, не содержит ошибок, в конечном итоге он создаст такой объект:
{
type: 'div',
props: {
children: 'Hello, World'
}
};
Эти объекты называются «React Elements». Вы можете думать о них как о описании того, что вы хотите видеть на экране. React возьмет эти объекты, использует их для построения DOM и обновит их.
Уведомление
Мы рекомендуем вам использовать"Бабель"Просмотрите результат компиляции JSX.
Компонент приложения, наконец, возвращает этот код JSX, поэтому мы используем Reactryrender
Метод отображает компонент приложения, и в итоге на экране отображается следующее:Hello, World"
содержание.
Использование JSX в качестве переменной
Поскольку JSX в конечном итоге будет скомпилирован в объект JS, поэтому мы можем использовать его как объект JS, он имеет тот же статус, что и объект JS, например, его можно назначить переменной, мы модифицируем метод рендеринга в приведенном выше код следующим образом:
render() {
const element = <div>Hello, World</div>;
return element;
}
Сохранив код, мы обнаруживаем, что содержимое, отображаемое в браузере, похоже на то, что было раньше.
Использование переменных в JSX
мы можем использовать фигурные скобки{}
Динамически вставлять значения переменных в JSX, Например, мы модифицируем метод рендеринга следующим образом:
render() {
const content = "World";
const element = <div>Hello, {content}</div>;
return element;
}
Сохраните код и обнаружите, что эффект в браузере остался прежним.
Использование JSX в JSX
Мы можем включить JSX внутрь JSX, чтобы мы могли писать произвольные уровни структуры HTML:
render() {
const element = <li>Hello, World</li>
return (
<div>
<ul>
{element}
</ul>
</div>
)
}
Добавление свойств узла в JSX
Мы можем добавлять атрибуты к тегам элементов точно так же, как в HTML, но мы должны подчинятьсяCamelCaseЗаконы, такие как атрибуты в HTMLdata-index
На узле JSX будет написано какdataIndex
.
const element = <div dataIndex="0">Hello, World</div>;
Уведомление
Все свойства в JSX должны быть заменены на верблюжьи имена, такие как
onclick
изменить наonClick
, единственный спец.class
, потому что в JSclass
зарезервированное слово, мы должныclass
изменить наclassName
.
const element = <div className="app">Hello, World</div>;
настоящий бой
Мы используем знания JSX, описанные в этом разделе, чтобы продолжить работу с нашим приложением todo.
Открыть в редактореsrc/index.js
Внесите следующие изменения в компоненты приложения:
class App extends React.Component {
render() {
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
return (
<ul>
<li>Hello, {todoList[0]}</li>
<li>Hello, {todoList[1]}</li>
<li>Hello, {todoList[2]}</li>
<li>Hello, {todoList[3]}</li>
</ul>
);
}
}
Как видите, мы используемconst
определяетtodoList
Константы массива и используемые в JSX{}
При динамической интерполяции вставляются четыре элемента массива.
Наконец, сохраните код, эффект в браузере должен быть таким:
намекать
Не нужно закрывать, просто используйте
npm start
Откройте сервер разработки, после изменения кода содержимое в браузере будет автоматически обновлено!
Вы могли заметить, что мы вручную получили четыре значения массива, а затем использовали по одному{}
Синтаксис вставляется в JSX и, наконец, визуализируется, что относительно примитивно, и мы упростим это написание в следующем списке и разделе Key.
В этом разделе мы изучили концепцию JSX и отработали соответствующие знания. Мы также ввели понятие компонентов, но не объяснили его подробно, в следующем подразделе мы подробно объясним знание компонентов.
Component
Одной из основных особенностей React является компонентизация, то есть мы разбиваем огромную бизнес-логику на небольшие компоненты с понятной логикой, а затем объединяем эти компоненты для выполнения бизнес-функций.
React предоставляет два способа написания компонентов: 1) функциональные компоненты и 2) компоненты класса.
функциональные компоненты
В React функциональные компоненты получают значение по умолчанию.props
параметры, а затем возвращает кусок JSX:
function Todo(props) {
return <li>Hello, 图雀</li>;
}
оprops
Мы объясним в следующем разделе.
компонент класса
Компонент представлен классом, который наследуется от React.Component.
class Todo extends React.Component {
render() {
return <li>Hello, 图雀</li>;
}
}
Мы обнаружили, что в компоненте класса нам нужноrender
Метод возвращает JSX, который необходимо отобразить.
Комбинация компонентов
Мы можем комбинировать различные компоненты для завершения сложной бизнес-логики:
class App extends React.Component {
render() {
return (
<ul>
<Todo />
<Todo />
</ul>
);
}
}
В приведенном выше коде мы используем компонент Todo, который мы определили ранее в компоненте класса App. Мы видим, что компонент начинается с<Component />
используется в виде, например, компонент Todo используется как<Todo />
, мы используем этот метод записи, когда у компонента Todo нет дочерних компонентов; когда компонент Todo должен содержать дочерние компоненты, нам нужно написать это в следующем виде:
class App extends React.Component {
render() {
return (
<ul>
<Todo>Hello World</Todo>
<Todo>Hello Tuture</Todo>>
</ul>
);
}
}
Рендеринг компонентов
Как мы упоминали в разделе 1,ReactDOM.render
Метод получает два параметра: 1) корневой компонент 2) монтируемый узел DOM, который может отображать содержимое компонента в HTML.
ReactDOM.render(<App />, document.getElementById('root'));
настоящий бой
Мы используем то, что узнали о компонентах в этом разделе, чтобы продолжить работу над нашим приложением. Мы пишем компонент класса Todo, представляющий один элемент списка дел, а затем используем компонент Todo в компоненте класса App.
Открытьsrc/index.js
файл, реализовать компонент Todo и настроить код компонента приложения следующим образом:
class Todo extends React.Component {
render() {
return <li>Hello, 图雀</li>;
}
}
class App extends React.Component {
render() {
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
return (
<ul>
<Todo />
<Todo />
<Todo />
<Todo />
</ul>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Сохраните код, и вы должны увидеть следующие результаты в своем браузере:
Вы могли заметить, что мы не используем массив todoList, который мы определили ранее, а используем четыре идентичных компонента Todo, которые унаследованы отReact.Component
Определите компонент Todo в виде класса, а затем вrender
вернулся в<li>Hello, 图雀</li>
, так что в итоге браузер отобразит четыре"Hello, 图雀"
. И поскольку компонент Todo не обязательно должен содержать подкомпоненты, мы пишем<Todo />
форма.
Теперь все 4 элемента списка дел имеют одно и то же содержимое, что немного однообразно.Вы можете подумать, что если вы можете настроить компонент, передавая параметры так же, как вызов функции, вы правы! В следующем разделе мы представим реквизиты, которые позволяют передавать содержимое компонентам для персонализированной настройки содержимого.
Props
React предоставляет Props для компонентов, так что при использовании компонентов вы можете передавать свойства компонентам для персонализированного рендеринга.
Использование свойств в функциональных компонентах
Функциональные компоненты получают по умолчаниюprops
Параметр, который представляет собой объект, содержащий содержимое, переданное от родительского компонента:
function Todo(props) {
return (
<li>Hello, {props.content}</li>
)
}
<Todo content="图雀" />
Передаем функциональный компонент Todo acontent
имущество, стоимость которого"图雀"
, все переданные свойства объединяются вprops
объект, который затем передается компоненту Todo, здесьprops
Объект такойprops = { content: "图雀" }
, если мы передадим еще одно свойство:
<Todo content="图雀" from="图雀社区" />
наконецprops
Объект будет выглядеть так:props={ content: "图雀", from: "图雀社区" }
.
Уведомление
Если передается компоненту
key
Свойства не объединяются в объект реквизита, поэтому мы не можем получить их в дочерних компонентах.key
свойства, которые мы подробно рассмотрим в разделе «Списки и ключи».
Использование свойств в компонентах класса
Базовые реквизиты в компонентах класса такие же, как и в функциональных компонентах, за исключениемthis.props
Чтобы получить содержимое свойства, переданное из родительского компонента:
class Todo extends React.Component {
render() {
return <li>Hello, {this.props.content}</li>;
}
}
<Todo content="图雀" />
настоящий бой
В этом разделе мы используем выученные знания реквизиты для продолжения приложений для наших доступа.
Открытьsrc/index.js
файл, настройте компоненты Todo и App соответственно, измененный код выглядит следующим образом:
import React from "react";
import ReactDOM from "react-dom";
class Todo extends React.Component {
render() {
return <li>Hello, {this.props.content}</li>;
}
}
class App extends React.Component {
render() {
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
return (
<ul>
<Todo content={todoList[0]} />
<Todo content={todoList[1]} />
<Todo content={todoList[2]} />
<Todo content={todoList[3]} />
</ul>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Обратите внимание, что мы начинаем снова, используя массив todoList, который мы определили ранее, а затем передаем каждому компоненту Todocontent
атрибут, назначьте каждый элемент массива отдельно и, наконец, используйте переданный в компоненте Todocontent
Атрибуты.
Сохраните изменения, и вы должны увидеть что-то вроде этого в вашем браузере:
Мы видим, наш контент вернулся, и то, что мы видели раньше в JSX, одно и то же, но на этот раз мы успешно использовали сборку Props для рендеринга полученного контента.
Состояние и жизненный цикл
React создает интерактивный контент, предоставляя состояние компонентам класса, то есть контент может измениться после рендеринга.
Определить состояние
Добавив в класс компонентconstructor
метод, где State определено и инициализировано:
constructor(props) {
super(props);
this.state = {
todoList: ["图雀", "图雀写作工具", "图雀社区", "图雀文档"]
};
}
Здесь свойство props, полученное методом конструктора, — это свойство props, о котором мы упоминали в предыдущем разделе, а React предусматривает, что каждый компонент, унаследованный от React.Component, должен быть добавлен в первую строку метода при определении метода конструктора.super(props)
.
Тогда мыthis.state
для определения состояния компонента и использования{ todoList: ["图雀", "图雀写作工具", "图雀社区", "图雀文档"] }
объект для инициализации состояния.
Использовать состояние
Мы можем передавать в нескольких местах в компонентеthis.state
способ использования состояния, например, в функциях жизненного цикла, о которых мы поговорим в этом разделе, например, в методе рендеринга:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
todoList: ["图雀", "图雀写作工具", "图雀社区", "图雀文档"]
};
}
render() {
return (
<ul>
<Todo content={this.state.todoList[0]} />
<Todo content={this.state.todoList[1]} />
<Todo content={this.state.todoList[2]} />
<Todo content={this.state.todoList[3]} />
</ul>
);
}
}
мы проходимthis.state.todoList
доступны в нашемconstructor
Состояние, определенное в методе, как видите, мы используемthis.state.todoList[0]
заменяет предыдущийtodoList[0]
.
Обновить состояние
мы проходимthis.setState
метод для обновления состояния, чтобы содержимое веб-страницы могло измениться после рендеринга:
this.setState({ todoList: newTodoList });
Уведомление
о
this.setState
Нам необходимо обратить внимание на следующие моменты:1) Это нельзя изменить напрямую
this.state
способ обновленияstate
:// 错误的 this.state.todoList = newTodoList;
2) Обновление состояния объединяется и обновляется:
такой как оригинал
state
Такова, что:constructor(props) { super(props); this.state = { todoList: [], nowTodo: '', }; }
тогда ты звонишь
this.setState()
способ обновленияstate
:this.setState({ nowTodo: "Hello, 图雀" });
React будет объединять обновления, которые скоро появятся
nowTodo
новый контент был объединен с оригинальнымthis.state
, при обновлении нашthis.state
Это будет выглядеть так:this.state = { todoList: [], nowTodo: "Hello, 图雀" };
Не потому, что он устанавливается отдельно
nowTodo
значение, это будетtodoList
покрывать.
функция жизненного цикла
React предоставляет функции жизненного цикла для отслеживания всего процесса компонента от создания до уничтожения. В основном он включает в себя три аспекта:
- Монтаж
- Обновление
- Размонтирование
Упрощенная схема жизненного цикла выглядит так:
Уведомление
Жизненный цикл React относительно сложен, мы не будем подробно объяснять каждую часть здесь, пользователи приведенной выше диаграммы могут попытаться понять его и составить о нем общее впечатление.
Чтобы просмотреть полную версию схемы жизненного цикла, перейдите по этой ссылке:Нажмите, чтобы просмотреть.
Здесь мы в основном объясняем часто используемые функции жизненного цикла при монтировании и выгрузке.
устанавливать
При монтаже обычно используются три основных метода:
constructor()
render()
componentDidMount()
constructor()
Вызывается при создании компонента, если вам не нужна инициализацияState
, то есть не требуетсяthis.state = { ... }
этот процесс, то вам не нужно определять этот метод.
render()
Метод — это метод, используемый для рендеринга содержимого при монтировании, и каждый компонент класса нуждается в методе рендеринга.
componentDidMount()
Метод — это метод, который будет вызываться после монтирования компонента на DOM-узле, здесь мы обычно инициируем какие-то асинхронные операции для получения данных на стороне сервера и т. д.
удалить
Есть только один способ удаления:
componentWillUnmount()
componentWillUnmount — это метод, который будет вызываться перед тем, как компонент будет размонтирован с DOM-узла.Как правило, мы уничтожаем таймеры и другой контент, который может вызвать утечку памяти.
настоящий бой
Мы используем то, что узнали в этом разделе о состоянии и жизненном цикле, чтобы продолжить работу с нашим приложением todo.
Открытьsrc/index.js
, измените код следующим образом:
import React from "react";
import ReactDOM from "react-dom";
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
class Todo extends React.Component {
render() {
return <li>Hello, {this.props.content}</li>;
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
todoList: []
};
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({
todoList: todoList
});
}, 2000);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
render() {
return (
<ul>
<Todo content={this.state.todoList[0]} />
<Todo content={this.state.todoList[1]} />
<Todo content={this.state.todoList[2]} />
<Todo content={this.state.todoList[3]} />
</ul>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Вы можете видеть, что мы в основном изменили пять частей:
- Переместите todoList за пределы компонента.
- Определите метод конструктора и, установив
this.state = { todoList: [] }
Чтобы инициализировать состояние компонента, здесь мыtodoList
Инициализирован пустым массивом. - Добавить к
componentDidMount
Метод жизненного цикла, когда компонент монтируется на узел DOM, устанавливается таймер со временем 2S и назначается наthis.timer
, который используется для уничтожения таймера при размонтировании компонента. После ожидания 2S используйтеthis.setState({ todoList: todoList })
чтобы обновить todoList компонента с помощью todoList, который мы только что переместили за пределы компонентаthis.state.todoList
. - Добавить к
componentWillUnMount
Методы жизненного цикла, когда компонент выгружается, черезclearTimeout(this.timer)
Чтобы очистить таймер, который мы установили ранее, чтобы предотвратить утечку памяти.
Сохраните измененный код, и мы должны увидеть процесс обновления контента в браузере.Когда компонент только что создан и смонтирован, экран браузера должен выглядеть так:
потому что мыthis.state
При инициализацииtodoList
Он установлен в пустой массив, поэтому в начале"Hello"
Назадthis.props.content
Контент пуст, у нас четыре"Hello, "
.
Затем, через 2S, мы можем увидеть знакомый контент:
Потому что через 2S мы будем в функции обратного вызова таймера.todoList
Установите тот, который определен вне компонентаtodoList
Массив состоит из четырех элементов, поэтому содержимое, отображаемое в браузере, такое же, как и раньше.
поздравляю! Успешно создал свой первый интерактивный компонент!
Прочитав это, вы можете немного устать, попробуйте встать с сидения, заняться чем-нибудь, выпить чашечку кофе, веселье продолжится позже 🙃
Список и ключ
В настоящее время у нас есть четыре компонента Todo, мы берем значения один за другим, а затем рендерим, что кажется немного примитивным и не масштабируемым, потому что, когда наш массив todoList очень большой (например, 100 элементов), нецелесообразно получать один за другим Фактически, в это время нам нужно вмешаться в петлю.
список компонентов рендеринга
JSX позволяет нам отображать список:
render() {
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
// 请注意:我们这里在 `map` 遍历时用了箭头函数简洁返回写法,直接用圆括号`()` 包裹需要返回的 `Todo` 组件,后面也是如此
const renderTodoList = todoList.map((todo) => (
<Todo content={todo} />
));
return (
<ul>
{renderTodoList}
</ul>
);
}
Мы делаем это, выполняя todoListmap
прошел, вернул список задач, а затем использовал{}
Синтаксис интерполяции отображает этот список.
Конечно, мы можем использовать выражения в JSX, поэтому приведенный выше код можно записать так:
render() {
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
return (
<ul>
{todoList.map((todo) => (
<Todo content={todo} />
))}
</ul>
);
}
Добавить ключ
React требует добавления к каждому компоненту в спискеkey
Атрибут для идентификации компонента в списке, чтобы при изменении содержимого списка: когда элементы добавлялись или удалялись, React могkey
Свойства эффективно создают и уничтожают компоненты списка:
render() {
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
return (
<ul>
{todoList.map((todo, index) => (
<Todo content={todo} key={index} />
))}
</ul>
);
}
Здесь мы используем списокindex
как компонентkey
значение, лучшая практика, рекомендованная сообществом React, — использовать уникальный идентификатор элемента данных списка какkey
значение, если ваши данные получены из базы данных, то первичный ключ данных элемента списка может использоваться какkey
.
здесьkey
Значения не передаются дочерним компонентам в качестве реквизита, React скомпилирует компонент сkey
Значения исключены из реквизита, который в конечном итоге является нашим первым компонентом Todo.props
следующим образом:
props = { content: "图雀" }
вместо того, что мы думаем:
props = { content: "图雀", key: 0 }
настоящий бой
Мы используем то, что узнали в этом разделе о списках и ключах, чтобы перейти к нашему приложению для работы со списком дел.
Открытьsrc/index.js
, код изменяется следующим образом:
import React from "react";
import ReactDOM from "react-dom";
const todoList = ["图雀", "图雀写作工具", "图雀社区", "图雀文档"];
class Todo extends React.Component {
render() {
return <li>Hello, {this.props.content}</li>;
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
todoList: []
};
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({
todoList: todoList
});
}, 2000);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
render() {
return (
<ul>
{this.state.todoList.map((todo, index) => (
<Todo content={todo} key={index} />
))}
</ul>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Как видите, мы изменили предыдущий ручной рендеринг элементов на использование встроенных выражений,this.state.todoList
Сопоставьте список, чтобы создать список компонентов Todo, а затем используйте списокindex
как компонентkey
значение, которое отображается последним.
Сохраните содержимое, просмотрите содержимое в браузере, мы видим, что содержимое изменит процесс, начало такое:
Вы найдете пустое место, а затем через 2S оно станет следующим:
Это потому, что в началеthis.state.todoList
Это пустой массив при инициализации в конструкторе,this.state.todoList
При выполнении операции map возвращается пустой массив, поэтому в нашем браузере нет содержимого.После монтирования компонента ждем 2S, и мы обновляемthis.state.todoList
содержание, вы увидите, что браузер был обновлен.
условный рендеринг
В React мы можем отображать различный контент в зависимости от различных ситуаций, что также называется условным рендерингом.
условное отображение if-else
render() {
if (this.props.content === "图雀") {
return <li>你好, {this.props.content}</li>;
} else {
return <li>Hello, {this.props.content}</li>;
}
}
В приведенном выше коде мы судимthis.props.content
, когда содержимое"图雀"
когда мы рендерим"你好, 图雀"
, для другого контента мы по-прежнему отображаем"Hello, 图雀"
.
Условный рендеринг троичных выражений
Мы также можем использовать тернарные выражения для условного рендеринга непосредственно в JSX:
render() {
return this.props.content === "图雀"? (
<li>你好, {this.props.content}</li>
) : (
<li>Hello, {this.props.content}</li>
);
}
Конечно, тернарные выражения также можно использовать для условной визуализации различных свойств элемента React:
render() {
return (
<li className={this.state.isClicked ? 'clicked' : 'notclicked'}>Hello, {this.props.content}</li>
)
}
Выше мы судим о компонентахthis.state.isClicked
имущество, еслиthis.state.isClicked
собственностьtrue
, то мы, наконец, визуализируем"clicked"
Добрый:
render() {
return (
<li className="clicked"}>Hello, {this.props.content}</li>
)
}
еслиthis.state.isClicked
дляfalse
, затем окончательный рендерингnotclicked
Добрый:
render() {
return (
<li className="notclicked">Hello, {this.props.content}</li>
)
}
настоящий бой
Мы используем то, что узнали в этом разделе, чтобы перейти к нашему приложению для работы со списком дел.
Открытьsrc/index.js
, внесите следующие изменения в компоненты Todo и App:
class Todo extends React.Component {
render() {
if (this.props.index % 2 === 0) {
return <li style={{ color: "red" }}>Hello, {this.props.content}</li>;
}
return <li>Hello, {this.props.content}</li>;
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
todoList: []
};
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({
todoList: todoList
});
}, 2000);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
render() {
return (
<ul>
{this.state.todoList.map((todo, index) => (
<Todo content={todo} key={index} index={index} />
))}
</ul>
);
}
}
Сначала мы передали компонент Todo в компонент Appindex
свойство, а затем в методе рендеринга компонента Todo,this.props.index
Сделайте вывод, если он четный, то отрисуйте красный текст, если нечетный, то останется без изменений.
Здесь мы даемli
элементальstyle
Свойства назначают объект для установки свойств CSS элементов в JSX, мы можем установить любые свойства CSS таким же образом:
// 黑底红字的 Hello, 图雀
<li style={{ color: "red", backgroundColor: "black"}}>Hello, 图雀</li>
Уведомление
Одна вещь, которую нужно изменить здесь, это что-то вроде
background-color
Такие свойства должны быть написаны в верблюжьем регистреbackgroundColor
. соответствующий напримерfont-size
, также пишется какfontSize
.
Сохраните код, и вы должны увидеть что-то вроде этого в своем браузере:
Мы видим, что эффект в браузере действительно заключается в том, что элементы с четными номерами (0 и 2 в массиве) становятся красным шрифтом, в то время как (1 и 3 в массиве) по-прежнему имеют черный стиль.
обработка событий
Обработка событий в элементах React похожа на HTML, за исключением того, что она написана немного иначе.
Обработка событий в JSX
Отличия здесь в основном заключаются в следующих двух моментах:
- События в React названы в верблюжьем регистре:
onClick
, вместо всех строчных букв:onclick
. - В JSX вы передаете обработчик события, а не строку.
В HTML мы обрабатываем события следующим образом:
<button onclick="handleClick()">点我</button>
В React нам нужно написать что-то вроде этого:
function Button() {
function handleClick() {
console.log('按钮被点击了');
}
return (
<button onClick={handleClick}>点我</button>
)
}
Обратите внимание, что мы определяем функциональный компонент выше, затем возвращаем кнопку и определяем событие щелчка и соответствующий метод обработки для кнопки.
Уведомление
Здесь наше событие click использует верблюжий регистр
onClick
чтобы назвать его, а свойство, переданное событию в JSX, является функцией:handleClick
вместо одной строки в предыдущем HTML:"handleClick()"
.
синтетическое событие
Когда мы писали обработку событий HTML, особенно при работе с формами, нам часто приходилось отключать свойства браузера по умолчанию.
намекать
Например, браузер обычно обновляется при отправке формы, но иногда мы хотим не обновлять браузер после отправки формы, поэтому нам нужно отключить свойства браузера по умолчанию.
В HTML мы отключаем свойство по умолчанию события, определенное для события, вызываяpreventDefault
или установить событиеcancelBubble
:
// 当点击某个链接之后,禁止打开页面
document.getElementById("myAnchor").addEventListener("click", function(event){
event.preventDefault()
});
В JSX обработка событий аналогична этой:
function Link() {
function handleClick(event) {
event.preventDefault();
console.log('链接被点击了,但是它不会跳转页面,因为默认行为被禁用了');
}
return (
<a onClick={handleClick} href="https://tuture.co">点我</a>
)
}
настоящий бой
Мы используем то, что узнали в этом разделе, чтобы продолжить работу с нашим приложением для работы со списком дел.
Массив todoList наших предыдущих элементов списка дел напрямую жестко запрограммирован в коде и не может быть добавлен, удален или изменен. Это довольно жестко. Более реалистичный todoList должен иметь функцию добавления. Реализация этой функции требует двух шаги:
- Позволяет пользователям вводить новые элементы списка дел.
- Добавьте этот вход в существующий список тодолиста.
В этом подразделе мы будем реализовывать содержание первого шага в будущем.
Открытьsrc/index.js
, внесите следующие изменения в содержимое компонента App:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
nowTodo: "",
todoList: []
};
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({
todoList: todoList
});
}, 2000);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
handleChange(e) {
this.setState({
nowTodo: e.target.value
});
}
render() {
return (
<div>
<div>
<input type="text" onChange={e => this.handleChange(e)} />
<div>{this.state.nowTodo}</div>
</div>
<ul>
{this.state.todoList.map((todo, index) => (
<Todo content={todo} key={index} index={index} />
))}
</ul>
</div>
);
}
}
Как видите, наш недавно добавленный код состоит из четырех основных частей:
- Сначала добавьте новое свойство в состояние
nowTodo
, который мы будем использовать для сохранения недавно введенного пользователем todo. -
div
div
input
div
onChange
e
this.handleChange
e
-
handleChange
this.setState
nowTodo
-
{}
nowTodo
this.state.nowTodo
this.state.nowTodo
src/index.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
nowTodo: "",
todoList: []
};
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({
todoList: todoList
});
}, 2000);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
handleChange(e) {
this.setState({
nowTodo: e.target.value
});
}
handleSubmit(e) {
e.preventDefault(e);
const newTodoList = this.state.todoList.concat(this.state.nowTodo);
this.setState({
todoList: newTodoList,
nowTodo: ""
});
}
render() {
return (
<div>
<form onSubmit={e => this.handleSubmit(e)}>
<input type="text" onChange={e => this.handleChange(e)} />
<button type="submit">提交</button>
</form>
<ul>
{this.state.todoList.map((todo, index) => (
<Todo content={todo} key={index} index={index} />
))}
</ul>
</div>
);
}
}
-
render
div
form
onSubmit
e
handleSubmit
-
e.preventDefault()
this.sate.todoList
nowTodo
this.setState
todoList
nowTodo
-
this.state.nowTodo
button
type
submit
handleSubmit
this.setState
nowTodo
Из-за нехватки места наш список дел не является полным, если у вас есть дополнительное время или вы хотите попрактиковаться в недавно изученных знаниях React, вот несколько идей, чтобы сделать наш список дел полным, мы. Эти функции будут упорядочены по сложность реализации:
- После добавления нового элемента списка дел очистите содержимое поля ввода, чтобы облегчить следующий ввод. это включает в себяКомпоненты, контролируемые Reactзнание.
- Допускается удаление отдельных элементов. Это включает в себя подкомпонентыИзменить состояние родительского компонентаЗнание.
- Позволяет пользователям вносить изменения в отдельные элементы.
- Позволяет пользователям искать элементы списка дел.
Хотите узнать больше интересных практических технических руководств? ПриходитьСообщество ТукеМагазин вокруг.