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

В настоящее время я учусь в школе Flatiron и изучаю разработку программного обеспечения. Недавно я завершил этапы 1 и 2, в которых рассматривались Vanilla JavaScript и React. Самый значительный период обучения, который я испытал в JavaScript, касался всего. Я работал в сфере продаж технологий и не имел опыта программирования.

React заставил меня столкнуться с двойной кривой обучения. Я имею в виду, там была вся эта история с новым синтаксисом и передачей реквизита? Я постоянно чесал голову. Но, говоря о подробностях, давайте теперь поговорим о «государстве».

Что такое государство и почему оно важно?

Думайте о состоянии в React как о термостате в вашем доме. Он отслеживает текущие настройки температуры. Если вы хотите сделать комнату теплее или прохладнее, вы регулируете термостат. Состояние React аналогичное; это похоже на динамический параметр, который управляет тем, что отображается на вашей веб-странице, и вы можете изменить его, чтобы обновить поведение вашего приложения.

В React мы используем State, чтобы наши компоненты могли хранить свою собственную информацию. Без него наши компоненты не смогли бы хранить или изменять свои данные, а наше приложение не могло бы делать интересные вещи или реагировать на то, что мы делаем. Давайте углубимся в практический пример того, когда может возникнуть состояние.

В следующем фрагменте кода мы используем состояние для выборки для управления и отображения данных:

import React, { useState, useEffect } from ‘react’;
function FetchData() {
const [data, setData] = useState(null);
useEffect(() => {
// Replace 'https://api.example.com/data' with the actual API endpoint
fetch('https://api.example.com/data')
.then(response => response.json())
.then(fetchedData => {
setData(fetchedData);
});
}, []);
return (
<div><p>{data.message}</p></div>
)}
export default FetchData;

Необходимо ли состояние в приведенном выше коде?

ДА.

Почему?

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

Управление данными. Когда вы получаете данные из внешнего API, вам нужно место для хранения этих данных и управления ими внутри вашего компонента. Состояние, созданное с помощью useState, предоставляет этот контейнер для хранения. У вас же не останется пустой корзины после похода за продуктами, верно? В моем примере выше const [data, setData] = useState(null); инициализирует переменную состояния (корзину) для хранения выбранных данных (продуктов).

Реактивность. В React, когда что-то в вашем компоненте меняется (например, полученные вами данные), React автоматически обновляет то, что отображается на экране. Итак, используя setData(fetchedData), вы сообщаете React запомнить новые данные. Когда это произойдет, React «заметит» изменение и обновит отображение вашего компонента обновленными данными. Таким образом, ваш компонент всегда сможет отображать на экране самую свежую информацию для просмотра пользователями.

Условный рендеринг с состоянием. Думайте об условном рендеринге как о волшебной кнопке, которая позволяет отображать на экране разные объекты в зависимости от того, есть ли у вас необходимые данные или нет. Эта волшебная кнопка — ваше состояние в React. Когда вы извлекаете данные, вы используете это состояние, чтобы решить, что показывать. Например, вы можете отображать сообщение типа «Загрузка…», пока ожидаете данные (поскольку ваше состояние знает, что вы ждете), а как только данные поступят, ваше состояние позволит вам переключиться на отображение фактических данных. Чтобы управлять этим переключением, вы можете использовать дополнительную переменную состояния, которая поможет вам отслеживать то, что в данный момент отображается на экране. Таким образом, ваш компонент знает, когда что показывать, делая ваш пользовательский интерфейс отзывчивым и динамичным.

Без использования состояния у вас не было бы возможности хранить и обновлять данные внутри вашего компонента. В результате ваш компонент не сможет отображать полученные данные или реагировать на изменения в этих данных. Итак, в этом примере использование состояния необходимо для эффективного управления и отображения полученных данных. Теперь поговорим о снятии состояния.

Состояние подъема и перемещения

«Поднятие состояния» — это я слышал снова и снова в первые дни работы с React, но понятия не имел, что это значит.

«Поднятие состояния» — это когда вы перемещаете управление частью данных или состоянием из дочернего компонента в родительский компонент. Это называется «подъемом состояния», потому что вы, по сути, передаете ответственность за управление этими данными компоненту более высокого уровня, делая их доступными как для родительского, так и для его дочерних компонентов. Так зачем его перемещать? Родителю легче с этим справиться. Плюс к этому тогда все дочерние компоненты будут иметь к нему доступ.

Допустим, у вас есть приложение со списком дел. Вы хотите управлять списком задач в родительском компоненте и отображать их в дочерних компонентах. Вот как вы можете переместить состояние:

  1. Определите состояние, которое необходимо переместить. Определите, какой частью состояния вы хотите управлять в дочернем компоненте. В этом случае предположим, что вы хотите, чтобы дочерний компонент отвечал за добавление новых элементов списка дел:
function TodoApp() {
// Parent component manages the list of to-dos
const [todos, setTodos] = useState([
{ id: 1, text: 'Buy groceries' },
{ id: 2, text: 'Clean the house' },
{ id: 3, text: 'Take out the trash' },
]);

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

// Parent Component (TodoApp)
function TodoApp() {
// Parent component manages the list of to-dos
const [todos, setTodos] = useState([
{ id: 1, text: 'Buy groceries' },
{ id: 2, text: 'Clean the house' },
{ id: 3, text: 'Take out the trash' },
]);
// Function to add a new to-do
const addTodo = (newTodo) => {
setTodos([…todos, newTodo]);
};// … Rest of the component}

3. Передайте функцию, созданную на шаге 2 (addTodo), в качестве свойства дочернему компоненту. Это позволяет дочернему компоненту вызывать функцию и обновлять состояние при необходимости:

// Parent Component
function TodoApp() {
// Parent component manages the list of to-dos
const [todos, setTodos] = useState([
{ id: 1, text: ‘Buy groceries’ },
// Function to add a new to-do
const addTodo = (newTodo) => {
setTodos([…todos, newTodo]); };
return (
<div>
{/* Pass the todos state and the addTodo function as props */}
<TodoList todos={todos} addTodo={addTodo} />
</div>
);
}

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

Хук useState (функциональные компоненты)

Раньше React в значительной степени полагался на компоненты классов, но теперь у нас есть функциональные компоненты. Они просты и предпочтительны. Один из способов управления состоянием функциональных компонентов — использование перехватчика useState в верхней части компонента.

Чтобы максимально упростить задачу, посмотрите на разницу между использованием компонента класса для простого счетчика:

import React, { Component } from ‘react’;
class CounterClass extends Component {
constructor() {
super();
this.state = {
count: 0,
};
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
)}};
export default CounterClass;

И функциональная составляющая в простом счетчике:

import React, { useState } from ‘react’;
function CounterFunction() {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment</button>
</div>
);
}
export default CounterFunction;

Вывод: функциональные компоненты лаконичны и легко читаются.

По мере роста вашего приложения React управление состоянием становится критически важным. Вот несколько советов:

  • Держите свое состояние как можно более минимальным.
  • Следуйте четкому соглашению об именах для переменных состояния.
  • Используйте функциональные обновления при изменении состояния на основе предыдущего состояния.
  • Компоненты классов не устарели, но функциональные компоненты с хуками стали нормой. Используйте компоненты класса для конкретных сценариев или при работе с устаревшим кодом. В противном случае используйте функциональные компоненты.
  • Хорошая организация компонентов имеет решающее значение. Поддерживайте чистоту и удобство обслуживания вашего кода, разделяя задачи. Каждый компонент должен иметь четкую и единую ответственность.

Спасибо, что прочитали мой пост в блоге. Надеюсь, это было информативно и помогло вам лучше понять ситуацию по сравнению с тем, когда вы впервые приехали!

Приятного кодирования,

Молли Т.