Глобальное создание состояний может снизить производительность вашего приложения. Узнайте, как эффективно создавать и использовать состояния в приложении React.

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

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

Базовый пример состояния в React

Вот очень простое приложение счетчика это пример того, как состояние обычно обрабатывается в React:

Импортировать {useState} от«реагировать»
Импортировать {Прилавок} от'прилавок'

функцияПриложение(){
константа [счетчик, setCount] = useState(0)
возвращаться<Прилавоксчитать={считать}setCount={setCount} />
}

экспортпо умолчанию Приложение

В строках 1 и 2 вы импортируете использовать состояние() хук для создания состояния и

instagram viewer
Прилавок компонент. Вы определяете считать государство и setCount способ обновления состояния. Затем вы передаете оба Прилавок компонент.

Прилавок Затем компонент отображает считать и звонки setCount для увеличения и уменьшения счетчика.

функцияПрилавок({количество, setCount}) {
возвращаться (

Вы не определили считать переменная и setCount функционируют локально внутри Прилавок компонент. Скорее, вы передали его из родительского компонента (Приложение). Другими словами, вы используете глобальное состояние.

Проблема с глобальными состояниями

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

Иногда это нормально, когда у вас есть состояние, которое используется многими компонентами. Но в этом случае ни один другой компонент не заботится о считать состояние, за исключением Прилавок компонент. Поэтому лучше перевести состояние в Прилавок компонент, где он фактически используется.

Перемещение состояния в дочерний компонент

Когда вы переводите состояние в Прилавок компонента, это будет выглядеть так:

Импортировать {useState} от«реагировать»

функцияПрилавок() {
константа [счетчик, setCount] = useState(0)
возвращаться (


Затем внутри вашего Приложение компонент, вам не нужно ничего передавать Прилавок компонент:

// импорт
функцияПриложение(){
возвращаться<Прилавок />
}

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

Обработка состояния в более сложных приложениях

Другая ситуация, в которой вы могли бы использовать глобальное состояние, связана с формами. Приложение компонент ниже передает данные формы (электронную почту и пароль) и метод установки вниз к ЛогинФорма компонент.

Импортировать { состояние использования } от"реагировать";
Импортировать {Форма входа} от"./ЛогинФорма";

функцияПриложение() {
константа [данныеформы, setFormData] = useState({
электронная почта: "",
пароль: "",
});

функцияобновитьформданные(новые данные) {
установитьДанныеФормы((предыдущий) => {
возвращаться { ...предыдущие, ...новые данные };
});
}

функцияonSubmit() {
консоль.log (данные формы);
}

возвращаться (
данные = {formData}
updateData = {updateFormData}
onSubmit={онСубмит}
/>
);
}

ЛогинФорма Компонент принимает информацию для входа в систему и отображает ее. Когда вы отправляете форму, она вызывает обновить данные функция, которая также передается от родительского компонента.

функцияЛогинФорма({ onSubmit, данные, updateData}) {
функцияручкаОтправить(е) {
e.preventDefault();
при отправке();
}

возвращаться (


Вместо того, чтобы управлять состоянием родительского компонента, лучше переместить состояние в ЛогинФорма.js, где вы будете использовать код. Это делает каждый компонент автономным и не зависит от другого компонента (т. е. родителя) для данных. Вот модифицированная версия ЛогинФорма:

Импортировать { использовать ссылку } от"реагировать";

функцияЛогинФорма({при отправке}) {
константа emailRef = useRef();
константа парольRef = useRef();

функцияручкаОтправить(е) {
e.preventDefault();
onSubmit({
электронная почта: emailRef.current.value,
пароль: passwordRef.current.value,
});
}

возвращаться (


Здесь вы привязываете ввод к переменной, используя ссылка атрибуты и useRef Реагируйте на хук вместо того, чтобы напрямую передавать методы обновления. Это поможет вам удалить многословный код и оптимизировать производительность формы с помощью хука useRef.

В родительском компоненте (App.js), вы можете удалить как глобальное состояние, так и обновитьданныеформы() метод, потому что он вам больше не нужен. Осталась только одна функция при отправке(), который вы вызываете из ЛогинФорма компонент для регистрации данных входа в консоль.

функцияПриложение() {
функцияonSubmit(formData) {
консоль.log (данные формы);
}

возвращаться (
данные = {formData}
updateData = {updateFormData}
onSubmit={онСубмит}
/>
);
}

Вы не только сделали свое состояние как можно более локальным, но и вообще устранили необходимость в каком-либо состоянии (и использовали судьи вместо). Так что ваши Приложение компонент стал значительно проще (имея только одну функцию).

Твой ЛогинФорма Компонент также стал проще, потому что вам не нужно было беспокоиться об обновлении состояния. Скорее, вы просто следите за двумя судьи, вот и все.

Обработка общего состояния

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

Примером является наличие TodoContainer родительский компонент с двумя дочерними компонентами: Список дел и TodoCount.

функцияTodoContainer() {
константа [todos, setTodos] = useState([])

возвращаться (
<>


</>
)
}

Оба этих дочерних компонента требуют дела государство, так что TodoContainer передает их обоим. В подобных сценариях вы должны сделать состояние как можно более локальным. В приведенном выше примере, помещая его внутрь TodosContainer является настолько локальным, насколько вы можете получить.

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

Для больших приложений управление состоянием только с помощью использовать состояние() крючок может оказаться трудным. В таких случаях вам, возможно, придется выбрать Контекстный API реакции или Реагировать Редукс эффективно управлять государством.

Узнайте больше о хуках React

Хуки составляют основу React. Используя хуки в React, вы можете избежать написания длинного кода, в котором в противном случае использовались бы классы. Хук useState(), бесспорно, является наиболее часто используемым хуком React, но есть и много других, таких как useEffect(), useRef() и useContext().

Если вы хотите научиться разрабатывать приложения с помощью React, вам нужно знать, как использовать эти хуки в своем приложении.