Работа с 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, но понятия не имел, что это значит.
«Поднятие состояния» — это когда вы перемещаете управление частью данных или состоянием из дочернего компонента в родительский компонент. Это называется «подъемом состояния», потому что вы, по сути, передаете ответственность за управление этими данными компоненту более высокого уровня, делая их доступными как для родительского, так и для его дочерних компонентов. Так зачем его перемещать? Родителю легче с этим справиться. Плюс к этому тогда все дочерние компоненты будут иметь к нему доступ.
Допустим, у вас есть приложение со списком дел. Вы хотите управлять списком задач в родительском компоненте и отображать их в дочерних компонентах. Вот как вы можете переместить состояние:
- Определите состояние, которое необходимо переместить. Определите, какой частью состояния вы хотите управлять в дочернем компоненте. В этом случае предположим, что вы хотите, чтобы дочерний компонент отвечал за добавление новых элементов списка дел:
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 управление состоянием становится критически важным. Вот несколько советов:
- Держите свое состояние как можно более минимальным.
- Следуйте четкому соглашению об именах для переменных состояния.
- Используйте функциональные обновления при изменении состояния на основе предыдущего состояния.
- Компоненты классов не устарели, но функциональные компоненты с хуками стали нормой. Используйте компоненты класса для конкретных сценариев или при работе с устаревшим кодом. В противном случае используйте функциональные компоненты.
- Хорошая организация компонентов имеет решающее значение. Поддерживайте чистоту и удобство обслуживания вашего кода, разделяя задачи. Каждый компонент должен иметь четкую и единую ответственность.
Спасибо, что прочитали мой пост в блоге. Надеюсь, это было информативно и помогло вам лучше понять ситуацию по сравнению с тем, когда вы впервые приехали!
Приятного кодирования,
Молли Т.