⚛️ 8 важнейших аспектов JavaScript, которые нужно освоить до изучения React

Изучение React без прочной базы JavaScript похоже на строительство дома без фундамента. В этой статье разберем 8 ключевых концепций, которые помогут тебе уверенно чувствовать себя в React-разработке и писать качественный код.

Этот материал взят из нашей еженедельной email-рассылки, посвященной фронтенду. Подпишитесь, чтобы быть в числе первых, кто получит дайджест.

Начинающие фронтендеры часто приступают к работе с React, не изучив досконально основные концепции JavaScript. В результате освоение библиотеки дается с трудом. Исправим эту ошибку!

Шаблонные литералы

Раньше конструирование строк в JS выглядело громоздко и неаккуратно:

let name = prompt("Как вас зовут?");
let greeting = alert("Привет, " + name + "!");

С появлением ES6 стало возможным использовать шаблонные литералы. Они создаются с помощью обратных кавычек `` и позволяют вставлять переменные прямо в строку:

let name = prompt("Как вас зовут?");
let greeting = alert(`Привет, ${name}`);

Шаблонные литералы очень упрощают динамическое создание строковых компонентов в React:

const name = 'Алиса';
const greeting = `Привет, ${name}! Как дела?`;
console.log(greeting); // Вывод: Привет, Алиса! Как дела?

const items = ['яблоко', 'банан', 'апельсин'];
const listItems = items.map(item => `<li>${item}</li>`).join('');
const list = `<ul>${listItems}</ul>`;

Деструктуризация

Деструктуризация в JavaScript позволяет извлекать значения из массивов или свойства объектов в отдельные переменные, что упрощает работу с данными. Чтобы деструктурировать объект, используют фигурные скобки { }, указывая нужные свойства:

const person = {
	firstName: 'Евгений',
	lastName: 'Онегин',
	jobPosition: 'фронтенд-разработчик',
	age: 30
};

const { lastName, firstName } = person;
console.log(firstName, lastName); // Вывод: Евгений Онегин

Вложенные объекты тоже можно деструктурировать:

const address = {
	street: 'Невский проспект',
	city: 'Санкт-Петербург',
	region: {
    	name: 'Северо-Западный федеральный округ',
    	abbreviation: ' СЗФО'
	}
};

Можно задавать значения по умолчанию, если свойство отсутствует:

const { street, city, region: { name } } = address;
console.log(street, city, name);
const config = {
	theme: 'light'
};

const { theme = 'dark' } = config;
console.log(theme); // Вывод: light

Деструктуризация позволяет переименовать свойства:

const person = {
	firstName: 'Татьяна',
	lastName: 'Ларина',
	jobDescription: 'UI-дизайнер',
	age: 25
};

const { firstName: givenName, lastName: familyName } = person;
console.log(givenName, familyName); // Вывод: Татьяна Ларина

Для деструктуризации массива используют квадратные скобки [], указывая индексы элементов:

const numbers = [1, 2, 3, 4, 5];
const [first, second] = numbers;
console.log(first, second); // Вывод: 1 2

В React деструктуризация позволяет легко извлекать и переименовывать данные в компонентах, делая код чище и понятнее:

import React from 'react';

const MyComponent = ({ name, age }) => {
  return (
	<div>
  	<h1>Привет, {name}!</h1>
  	<p>Вам {age} лет.</p>
	</div>
  );
};

Операторы rest и spread

Эти операторы часто применяются с деструктуризацией и помогают эффективно работать с данными, что особенно полезно в React для передачи пропсов, клонирования и объединения объектов и массивов. Хотя rest и spread используют одинаковый синтаксис , они решают разные задачи.

Оператор ...rest собирает оставшиеся элементы массива или свойства объекта в новый массив или объект:

const numbers = [1, 2, 3, 4, 5];
const [first, ...rest] = numbers;
console.log(rest); // Вывод: [2, 3, 4, 5]

Оператор spread используется для распаковки массива или объекта, позволяя легко добавлять или копировать их содержимое:

const numbers = [1, 2, 3];
const newArray = [...numbers, 4, 5];
console.log(newArray); // Вывод: [1, 2, 3, 4, 5]

В React spread оператор часто используется для копирования объектов, объединения свойств или передачи пропсов:

const person = { name: 'Евгений', age: 30 };
const newPerson = { ...person, city: 'Москва' };
console.log(newPerson); // Вывод: { name: 'Евгений', age: 30, city: 'Москва' }

Тернарные операторы

Тернарные операторы в JavaScript позволяют записывать условные выражения компактнее, чем с помощью if/else:

let age = 19;
const message = age >= 18 ? 'Вы совершеннолетний.' : 'Вы несовершеннолетний.';
console.log(message); // Вывод: Вы совершеннолетний.

В React тернарные операторы используются для условного рендеринга:

const MyComponent = ({ isLoggedIn }) => {
	return (
    	<div>
    	{isLoggedIn ? (
        	<p>Добро пожаловать!</p>
    	) : (
        	<p>Пожалуйста, войдите в систему.</p>
    	)}
    	</div>
	);
};

Стрелочные функции

Стрелочные функции, добавленные в ES6, предлагают краткий синтаксис, улучшая читаемость и поддержку кода:

const greet = name => `Привет, ${name}!`;
console.log(greet('Вася')); // Вывод: Привет, Вася!

Они часто используются в React для создания коротких и понятных обработчиков и других вспомогательных функций:

<button onClick={() => this.handleClick()}>Нажми меня</button>

Стрелочные функции удобно использовать с методами map, filter и reduce:

const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map(number => number * 2);

Кроме того, в React можно передавать стрелочные функции в качестве пропсов:

const MyComponent = ({ name, onButtonClick }) => {
	return (
    	<button onClick={onButtonClick}>Нажми меня</button>
	);
};

Короткие замыкания

Техника короткого замыкания в JavaScript позволяет оптимизировать выполнение логических выражений, останавливая вычисления, как только результат становится очевидным. В React это помогает упростить работу с условиями и значениям по умолчанию для переменных и пропсов.

Оператор && прекращает выполнение, если первое значение ложно, и сразу возвращает его. Если первое значение истинно, возвращается второе значение:

const isLoggedIn = true;
const greeting = isLoggedIn && <p>Добро пожаловать!</p>;

Оператор || работает наоборот: если первое значение истинно, оператор возвращает его, иначе – второе значение:

const username = 'Татьяна';
const greeting = username || 'Гость';

Оператор объединения с null ?? возвращает первое значение, если оно не null или undefined, иначе возвращает второе значение:

let numberOfBooksRead = 0;
const hasRead = numberOfBooksRead ?? 'Нет данных'; 
// hasRead = 0

Оператор ?. безопасно проверяет наличие вложенных свойств, возвращая undefined, если значение не существует:

const user = { address: { street: 'Ул. Зеленая, 123' } };
const street = user?.address?.street;

Основные методы массивов

Массивы – базовая структура данных в JavaScript, которая хранит упорядоченные элементы и может содержать данные разных типов. В React они необходимы для работы с данными, позволяя отображать, фильтровать и обрабатывать элементы динамического интерфейса.

map() создает новый массив, применяя функцию к каждому элементу исходного массива. Часто используется для обновления элементов:

const items = ['яблоко', 'банан', 'апельсин'];
const updatedItems = items.map(item => item === 'яблоко' ? 'грейпфрут' : item);

filter() создает новый массив только из элементов, которые соответствуют заданному условию. Подходит для удаления ненужных элементов:

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(number => number % 2 === 0);

reduce() применяет функцию к каждому элементу массива, сокращая массив до одного значения:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);

Среди других методов массивов, которые особенно часто используются в React:

  • sort() – сортирует элементы массива на месте.
  • flatMap() – распаковывает вложенные массивы и применяет функцию ко всем элементам.
  • find() – возвращает первый элемент, удовлетворяющий условию.

При сложной обработке данных, результаты которой последовательно изменяют интерфейс, методы массивов можно использовать цепочкой:

const users = [
	{ name: 'Болконский', age: 30 },
	{ name: 'Безухов', age: 28 },
	{ name: 'Онегин', age: 26 }
];

const adultUsers = users
	.filter(user => user.age >= 18)
	.map(user => ({ name: user.name, age: user.age }));

Получение данных

Получение данных – один из важнейших аспектов разработки фронтенда: данные используются для заполнения компонентов, обновления интерфейса и создания динамичного пользовательского опыта.

Промисы и fetch

Промисы представляют собой объект, который обозначает окончание (или неудачу) асинхронной операции. Функция fetch() – это встроенная функция JavaScript, которая возвращает промис, представляющий запрос на получение ресурса:

fetch('https://api.example.com/data')
	.then(response => response.json())
	.then(data => {
               	// Обработка данных здесь
               	console.log(data);
	})
	.catch(error => {
               	// Обработка ошибок здесь
               	console.error(error);
	});

async/await

Синтаксис async/await предлагает более удобный способ работы с промисами, позволяя писать асинхронный код, который выглядит как синхронный:

async function fetchData() {
	try {
               	const response = await fetch('https://api.example.com/data');
               	const data = await response.json();
               	console.log(data);
	} catch (error) {
               	console.error(error);
	}
}

fetchData();

Получение данных в компонентах React

В компонентах React данные обычно запрашиваются в методах жизненного цикла, таких как componentDidMount, или с помощью хука useEffect. Это гарантирует, что данные загружаются после монтирования компонента и установки начального состояния:

import React, { useEffect, useState } from 'react';
function MyComponent() {
	const [data, setData] = useState(null);

	useEffect(() => {
    	const fetchData = async () => {
        	try {
            	const response = await fetch('https://api.example.com/data');
            	const data = await response.json();
            	setData(data);
        	} catch (error) {
            	console.error(error);
        	}
    	};

    	fetchData();
	}, []);

	return (
    	<div>
        	{data ? (
            	<p>Данные: {JSON.stringify(data)}</p>
        	) : (
            	<p>Загрузка...</p>
        	)}
    	</div>
	);
}

В процессе получения данных важно обрабатывать ошибки с помощью блоков try/catch для перехвата исключений и предоставления соответствующей обратной связи пользователю.

***

Frontend Basic: от нуля до первых проектов в портфолио

Хотите освоить Frontend с нуля? В Proglib Academy запустили практический курс:

  • 26 видеоуроков и 28 практических заданий с пожизненным доступом
  • Стек: HTML, CSS, JavaScript, React.js, Git
  • Проекты для портфолио: от простой верстки до полноценного интернет-магазина
  • Персональные консультации с действующими разработчиками из Газпромбанка и Айньюс

Особенно круто, что курс построен по принципу «делай как я» — смотришь, повторяешь, получаешь фидбек. Никакой воды и лишней теории.

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ