ВГТУ
2024-12-03
React - это библиотека JavaScript, разработанная компанией Facebook, предназначенная для создания интерактивных пользовательских интерфейсов. С помощью React разработчики могут создавать компоненты пользовательского интерфейса, которые являются независимыми и могут быть повторно использованы в различных частях приложения. React использует концепцию виртуального DOM для эффективного обновления пользовательского интерфейса, что приводит к улучшенной производительности веб-приложений.
npm (Node Package Manager) - это менеджер пакетов для языка программирования JavaScript
, в первую очередь используемый для управления модулями Node.js
. npm
устанавливается вместе с Node.js
, что означает, что при загрузке Node.js
вы автоматически получаете установленный npm
на вашей системе.
npm
позволяет разработчикам устанавливать, обмениваться и управлять зависимостями или пакетами для их проектов Node.js
. Он также предоставляет интерфейс командной строки, который позволяет разработчикам взаимодействовать с npm для выполнения различных задач, таких как установка пакетов, обновление пакетов, управление зависимостями и запуск скриптов, определенных в файле package.json
проекта.
Некоторые распространенные команды npm
включают в себя:
npm install
: Устанавливает зависимости, перечисленные в файле package.json.npm install <package-name>
: Устанавливает определенный пакет локально.npm install -g <package-name>
: Устанавливает пакет глобально.npm update
: Обновляет пакеты до их последних версий на основе диапазонов версий, указанных в файле package.json.npm uninstall <package-name>
: Удаляет пакет.npm search <keyword>
: Поиск пакетов в реестре npm.npm init
: Инициализирует новый проект Node.js и создает файл package.json.npm start
: Запускает скрипт “start”, определенный в файле package.json.npm test
: Запускает скрипт “test”, определенный в файле package.json.Создадим HTML файл со следующим содержимым:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function MyApp() {
return <h1>Hello, world!</h1>;
}
const container = document.getElementById('root');
const root = ReactDOM.createRoot(container);
root.render(<MyApp />);
</script>
<!--
Note: this page is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Read this page for starting a new React project with JSX:
https://react.dev/learn/start-a-new-react-project
Read this page for adding React with JSX to an existing project:
https://react.dev/learn/add-react-to-an-existing-project
-->
</body>
</html>
Этот файл можно использовать для того, чтобы попробовать React без необходимости что-либо устанавливать. Но такой вариант будет очень медленным и не подходит для реального использования.
Давайте создадим новое приложение React с использованием Create React App, который является одним из наиболее распространенных способов начать новый проект React. Вам потребуется установленный Node.js для этого.
Шаги:
Установите Create React App, выполнив следующую команду в терминале (если вы еще этого не сделали):
npm install -g create-react-app
Создайте новое приложение, выполните:
npx create-react-app my-app
Замените my-app
на имя вашего приложения.
Перейдите в каталог вашего нового приложения:
cd my-app
Запустите приложение:
npm start
Это запустит разработческий сервер, и ваше новое приложение будет доступно по адресу http://localhost:3000/
.
Теперь ваше новое приложение React готово к использованию! Вы можете редактировать файлы в каталоге src
для создания своего приложения, добавлять новые компоненты, стили и многое другое.
Для создания React-приложения с использованием Next.js, вам следует выполнить следующие шаги:
Установка Node.js и npm: Убедитесь, что у вас установлен Node.js и npm на вашем компьютере. Вы можете загрузить их с официального сайта Node.js: nodejs.org.
Создание нового проекта Next.js: Выполните следующие команды в вашем терминале или командной строке, чтобы создать новый проект Next.js:
Где my-next-app
- это название вашего проекта. Эта команда создаст новый каталог my-next-app
и установит в него структуру проекта Next.js.
Запуск проекта: После того, как проект был создан, перейдите в каталог проекта:
И затем запустите проект с помощью следующей команды:
Это запустит Next.js в режиме разработки. По умолчанию ваше приложение будет доступно по адресу http://localhost:3000
.
Начните разработку: Теперь вы можете начать разрабатывать свое приложение. Файлы React-компонентов можно создавать в каталоге pages
. Каждый файл в этом каталоге становится маршрутом в вашем приложении.
Например, создайте файл pages/index.js
с содержимым:
После сохранения этого файла, вы увидите изменения на вашем локальном сервере, и ваше приложение Next.js автоматически обновится.
Это основы создания React-приложения с использованием Next.js. Можно найти дополнительную информацию и руководства на официальном сайте Next.js: nextjs.org/docs.
Компоненты в React представляют собой независимые блоки пользовательского интерфейса, которые объединяют в себе логику и отображение. Они используются для создания интерактивных элементов на веб-страницах. Компоненты позволяют разбить сложный интерфейс на более мелкие, самодостаточные части, что делает код более организованным, повторно используемым и легким для поддержки и расширения. Компоненты также позволяют упростить разработку, так как различные части интерфейса могут быть разработаны и отлажены независимо друг от друга.
JSX (JavaScript XML) - это расширение синтаксиса JavaScript, которое позволяет писать код, похожий на HTML, непосредственно в JavaScript. JSX используется в React для определения структуры пользовательского интерфейса, то есть для описания того, как компоненты должны быть отображены на экране. JSX делает код более читаемым и понятным, а также упрощает работу с элементами интерфейса.
Пример использования JSX в React:
Теги: JSX использует синтаксис тегов, похожий на HTML, для определения элементов. Теги могут быть самозакрывающимися, как <input />
, или иметь соответствующие открывающие и закрывающие теги, как <div></div>
.
Вложенность: Элементы JSX могут быть вложенными друг в друга, как в HTML.
JavaScript выражения: Внутри JSX можно использовать JavaScript выражения, заключая их в фигурные скобки {}
. Это позволяет вставлять переменные, вызовы функций и другие выражения прямо в JSX.
Стили и атрибуты: Атрибуты элементов JSX можно определять так же, как в HTML. Для определения стилей используется объект JavaScript в атрибуте style
.
Комментарии: Комментарии в JSX должны быть заключены в фигурные скобки {/* */}
.
Преимущества:
Читаемость и понятность: JSX делает код более читаемым и понятным, особенно для разработчиков, знакомых с HTML.
Интеграция JavaScript: JSX позволяет использовать JavaScript выражения непосредственно внутри разметки, что упрощает взаимодействие с данными и логикой приложения.
Статические анализаторы кода: JSX позволяет статическим анализаторам кода, таким как ESLint, предоставлять дополнительные проверки и подсказки.
Недостатки:
Новый синтаксис: Для некоторых разработчиков JSX может быть новым и необычным синтаксисом, требующим времени для освоения.
Необходимость компиляции: Браузеры не могут напрямую интерпретировать JSX, поэтому код на JSX требует предварительной компиляции в JavaScript с помощью инструментов, таких как Babel.
Вероятность возникновения ошибок: Неправильное использование JSX может привести к ошибкам, особенно при вставке JavaScript выражений.
Виртуальный DOM (VDOM) - это концепция, используемая в React для улучшения производительности обновления пользовательского интерфейса. Вместо того чтобы напрямую обновлять реальный DOM при каждом изменении данных, React создает в памяти виртуальное представление DOM. Это виртуальное дерево DOM содержит копию текущего состояния интерфейса и позволяет React определить минимальное количество манипуляций DOM, необходимых для обновления интерфейса.
Изменение состояния: Когда состояние компонента React изменяется (например, пользователь вводит данные в форму или происходит получение данных с сервера), React создает новое виртуальное дерево DOM на основе измененного состояния.
Сравнение виртуального DOM: React сравнивает новое виртуальное дерево DOM с предыдущим, сохраненным в памяти. Он анализирует различия между ними, чтобы определить, какие части интерфейса были изменены.
Вычисление минимальных изменений: React вычисляет минимальное количество манипуляций DOM, необходимых для того, чтобы применить изменения из нового виртуального DOM к реальному DOM. Этот процесс называется “согласованием” (reconciliation).
Обновление реального DOM: После того как React определил необходимые изменения, он применяет их к реальному DOM, обновляя только те элементы, которые были изменены.
Уменьшение количества операций с DOM: Использование виртуального DOM позволяет уменьшить количество манипуляций с реальным DOM за счет оптимизации и минимизации обновлений, что улучшает производительность приложения.
Более эффективные обновления: За счет сравнения виртуального DOM с предыдущим состоянием, React определяет только те части интерфейса, которые действительно изменились, и обновляет только их, что делает процесс обновления более эффективным.
Повышение отзывчивости интерфейса: Благодаря более быстрым и эффективным обновлениям интерфейса пользователь получает более отзывчивый опыт использования приложения.
Улучшенный опыт разработчика: Разработчики могут сосредоточиться на логике приложения, не беспокоясь о низкоуровневых деталях манипуляций с DOM, благодаря тому, что React заботится об этом автоматически.
Принцип однонаправленного потока данных в React означает, что данные передаются от родительских компонентов к дочерним компонентам через свойства (props). Это означает, что данные могут изменяться только в родительском компоненте, и дочерние компоненты не могут изменять данные напрямую. Если дочерний компонент хочет изменить данные, он должен вызвать функцию обратного вызова, переданную ему в качестве свойства.
props
.setState()
.useState
, для добавления состояния.// Родительский компонент
function ParentComponent() {
const data = "Hello from Parent";
return <ChildComponent data={data} />;
}
// Дочерний компонент
function ChildComponent(props) {
return <p>{props.data}</p>;
}
// Родительский компонент
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return <ChildComponent count={this.state.count} increment={this.incrementCount} />;
}
}
// Дочерний компонент
function ChildComponent(props) {
return (
<div>
<p>Count: {props.count}</p>
<button onClick={props.increment}>Increment</button>
</div>
);
}
В обоих примерах данные передаются от родительского компонента к дочернему компоненту через свойства (props). Передача данных через состояние и функции обратного вызова происходит аналогичным образом.
Жизненный цикл компонентов в React представляет собой последовательность этапов, через которые проходит компонент, начиная с его создания и заканчивая удалением из DOM. Каждый этап жизненного цикла предоставляет различные методы, которые позволяют реагировать на определенные события и выполнять соответствующие действия.
constructor()
: Вызывается при создании компонента. Используется для инициализации состояния и привязки методов.render()
: Обязательный метод, который возвращает React-элементы, описывающие структуру компонента.componentDidMount()
: Вызывается сразу после того, как компонент был добавлен в DOM. Используется для выполнения загрузки данных с сервера, подписки на события или других побочных эффектов.shouldComponentUpdate()
: Вызывается перед рендерингом компонента. Используется для оптимизации производительности, путем предотвращения лишних обновлений.render()
: Обновляет представление компонента в соответствии с новыми данными.componentDidUpdate()
: Вызывается после обновления компонента и обновления DOM. Используется для выполнения действий, которые зависят от изменений в компоненте или DOM.componentWillUnmount()
: Вызывается перед тем, как компонент будет удален из DOM. Используется для отмены подписок, очистки ресурсов или выполнения других необходимых действий перед удалением компонента.componentDidCatch()
: Вызывается при возникновении ошибки в методах жизненного цикла или в рендеринге дочерних компонентов. Используется для обработки ошибок и предотвращения падения всего приложения.componentDidMount()
для загрузки данных с сервера после создания компонента.shouldComponentUpdate()
для предотвращения лишних ререндеров компонента при изменении состояния или свойств.componentWillUnmount()
для отписки от событий, очистки таймеров или других ресурсов перед удалением компонента.componentDidCatch()
для отлова и обработки ошибок, которые могут возникнуть в компонентах или их дочерних элементах.Хуки (Hooks) - это новое API, предоставленное React с версии 16.8, которое позволяет функциональным компонентам использовать состояние и другие возможности React, которые ранее были доступны только в классовых компонентах. Хуки позволяют писать более чистый и лаконичный код, делая его более читаемым и поддерживаемым.
Хук useState
используется для добавления локального состояния в функциональные компоненты.
Он принимает начальное значение состояния и возвращает пару значений: текущее значение состояния и функцию для его обновления.
Пример:
Хук useEffect
позволяет выполнить побочные эффекты в функциональных компонентах.
Он принимает функцию-эффект и опциональный массив зависимостей и запускает этот эффект после каждого рендера компонента.
Пример:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
Хук useContext
используется для получения значения контекста React.
Он принимает объект контекста, возвращаемый функцией React.createContext()
, и возвращает текущее значение контекста.
Пример:
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedComponent() {
const theme = useContext(ThemeContext);
return <p>Current theme: {theme}</p>;
}
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
}
Хук useMemo
в React используется для мемоизации результатов выполнения функции, чтобы избежать избыточных вычислений во время рендеринга компонентов. Он принимает функцию и массив зависимостей, и возвращает кешированное значение функции.
Назначение хука useMemo:
Когда функциональный компонент рендерится, все переменные, определенные внутри его функции, пересоздаются при каждом вызове рендера. Это может привести к избыточным вычислениям, особенно если вычисления занимают много времени. useMemo
предоставляет способ сохранить результаты выполнения функции между рендерами компонента, чтобы они не пересчитывались каждый раз.
Синтаксис:
computeExpensiveValue
- функция, результат выполнения которой мы хотим мемоизировать.[a, b]
- массив зависимостей. Если хотя бы одно значение из этого массива изменится, useMemo
вызовет функцию computeExpensiveValue
снова.Пример использования хука useMemo:
Рассмотрим пример, где у нас есть компонент, который отображает сумму элементов массива. Если массив или его элементы не изменились, мы можем использовать useMemo
, чтобы избежать повторного вычисления суммы каждый раз при рендеринге.
import React, { useMemo, useState } from 'react';
function ArraySum({ array }) {
const sum = useMemo(() => {
console.log('Calculating sum...');
return array.reduce((acc, curr) => acc + curr, 0);
}, [array]);
return <div>Sum: {sum}</div>;
}
function App() {
const [array, setArray] = useState([1, 2, 3, 4, 5]);
const updateArray = () => {
setArray(prevArray => [...prevArray, prevArray.length + 1]);
};
return (
<div>
<ArraySum array={array} />
<button onClick={updateArray}>Add Element</button>
</div>
);
}
export default App;
В этом примере useMemo
используется для вычисления суммы элементов массива только в случае изменения самого массива. Каждый раз, когда мы добавляем новый элемент в массив, рендерится компонент ArraySum
, но вычисление суммы не происходит заново, если массив не изменился. Это позволяет избежать ненужных вычислений и повышает производительность приложения.
Хук useReducer
в React предоставляет альтернативный способ управления состоянием компонентов по сравнению с useState
. Он предлагает более мощный способ управления состоянием, особенно для более сложных состояний, которые могут быть связаны с различными действиями. useReducer
основан на принципе Redux и позволяет управлять состоянием компонента с помощью функции редуктора.
Назначение хука useReducer:
Хук useReducer
предназначен для управления состоянием компонента, где состояние представляет собой объект с данными, а изменения состояния происходят через действия (actions). Редуктор (reducer) - это функция, которая принимает предыдущее состояние и действие, и возвращает новое состояние. useReducer
позволяет компоненту обрабатывать сложные логические операции и управлять состоянием более явно.
Синтаксис:
reducer
- функция, которая принимает текущее состояние и действие, и возвращает новое состояние.initialState
- начальное значение состояния.Пример использования хука useReducer:
Предположим, у нас есть простой счетчик, который можно увеличивать и уменьшать. Мы можем использовать useReducer
, чтобы управлять состоянием этого счетчика.
import React, { useReducer } from 'react';
// Редуктор для управления состоянием счетчика
const counterReducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
};
function Counter() {
// Использование useReducer для управления состоянием
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
</div>
);
}
export default Counter;
В этом примере мы определили редуктор counterReducer
, который обрабатывает действия 'INCREMENT'
и 'DECREMENT'
, изменяя состояние счетчика соответственно. Затем мы используем useReducer
, чтобы управлять состоянием счетчика в компоненте Counter
. Каждый раз, когда пользователь нажимает кнопки “Increment” или “Decrement”, мы диспетчеризуем соответствующее действие, которое передается редуктору, и состояние обновляется соответственно. Это позволяет нам управлять состоянием компонента более явно и четко определять логику обработки действий.
Хук useCallback
в React используется для мемоизации колбэк-функций, чтобы предотвратить их повторное создание при каждом рендере компонента. Это позволяет оптимизировать производительность компонентов, особенно в случаях, когда колбэк-функции передаются как пропсы дочерним компонентам и могут вызываться заново при каждом рендере.
Назначение хука useCallback:
Когда функциональный компонент рендерится, функции, определенные внутри его функции, пересоздаются при каждом вызове рендера. Это может привести к избыточным ререндерам дочерних компонентов, которым передаются эти функции в качестве пропсов. useCallback
позволяет сохранить эти колбэк-функции между рендерами, чтобы они не пересоздавались каждый раз.
Синтаксис:
callback
- функция, которую мы хотим мемоизировать.dependencies
- массив зависимостей. Если хотя бы одно значение из этого массива изменится, useCallback
создаст новую функцию.Пример использования хука useCallback:
Рассмотрим пример, где у нас есть родительский компонент, который передает колбэк-функцию дочернему компоненту для обработки события. Мы можем использовать useCallback
, чтобы мемоизировать эту колбэк-функцию и предотвратить ее повторное создание при каждом рендере родительского компонента.
import React, { useState, useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
// Мемоизированная колбэк-функция с помощью useCallback
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);
return (
<div>
<p>Count: {count}</p>
<ChildComponent onClick={handleClick} />
</div>
);
}
function ChildComponent({ onClick }) {
return <button onClick={onClick}>Increment</button>;
}
export default ParentComponent;
В этом примере мы используем useCallback
, чтобы мемоизировать колбэк-функцию handleClick
, которая увеличивает счетчик при каждом вызове. Поскольку зависимостей нет ([]
), эта функция будет создана только один раз при первом рендере ParentComponent
, а затем будет использоваться при последующих рендерах без повторного создания. Это позволяет оптимизировать производительность компонента, предотвращая ненужные ререндеры.
Хук useRef
в React используется для создания изменяемого объекта, который будет сохраняться между рендерами компонента. Основное назначение useRef
- это получение ссылки на DOM-элемент или другой объект в функциональном компоненте.
Назначение хука useRef:
Ссылка на DOM-элементы: useRef
позволяет получить ссылку на DOM-элемент, чтобы иметь возможность взаимодействовать с ним напрямую из функционального компонента.
Сохранение значения между рендерами: useRef
также может использоваться для сохранения значений между рендерами компонента без вызова повторного рендера. Значение, сохраненное в объекте ref
, будет сохраняться между рендерами и изменениями состояния без вызова эффектов повторного рендера.
Синтаксис:
initialValue
- необязательный параметр, который устанавливает начальное значение ссылки. Это может быть любое значение, включая DOM-элемент или объект.Пример использования хука useRef:
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus Input</button>
</div>
);
}
В этом примере мы используем useRef
, чтобы получить ссылку на <input>
элемент и сделать его активным при нажатии на кнопку.
import React, { useState, useRef } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
const intervalRef = useRef();
const startTimer = () => {
intervalRef.current = setInterval(() => {
setSeconds(prevSeconds => prevSeconds + 1);
}, 1000);
};
const stopTimer = () => {
clearInterval(intervalRef.current);
};
return (
<div>
<p>Timer: {seconds} seconds</p>
<button onClick={startTimer}>Start Timer</button>
<button onClick={stopTimer}>Stop Timer</button>
</div>
);
}
В этом примере мы используем useRef
, чтобы сохранить ссылку на интервал таймера между рендерами. Это позволяет нам запускать и останавливать таймер, сохраняя при этом состояние компонента без вызова повторного рендера.