Criar os estados globalmente pode diminuir o desempenho do seu aplicativo. Saiba como você pode criar e utilizar estados de forma eficaz em seu aplicativo React.

Se você escreveu muito código React, é provável que tenha usado o estado incorretamente. Um erro comum que muitos desenvolvedores React cometem é armazenar estados globalmente no aplicativo, em vez de armazená-los nos componentes onde são usados.

Saiba como você pode refatorar seu código para utilizar o estado local e por que fazer isso é sempre uma boa ideia.

Exemplo básico de estado em React

aqui está um muito aplicação de contador simples que exemplifica como o estado é normalmente tratado no React:

importar {useState} de'reagir'
importar {Contador} de'contador'

funçãoAplicativo(){
const [count, setCount] = useState(0)
retornar<Contadorcontar={contar}setCount={setCount} />
}

exportarpadrão Aplicativo

Nas linhas 1 e 2, você importa o useState() gancho para criar o estado, e o Contador componente. Você define o contar estado e setCount método para atualizar o estado. Então você passa ambos para baixo para o Contador componente.

O Contador componente, em seguida, renderiza o contar e chamadas setCount para aumentar e diminuir a contagem.

funçãoContador({contar, definirContagem}) {
retornar (

Você não definiu o contar variável e setCount funcionar localmente dentro do Contador componente. Em vez disso, você o passou do componente pai (Aplicativo). Em outras palavras, você está usando um estado global.

O problema com os Estados globais

O problema de usar um estado global é que você está armazenando o estado em um componente pai (ou pai de um pai) e então passando-o como adereços para o componente onde esse estado é realmente necessário.

Às vezes, isso é bom quando você tem um estado compartilhado por vários componentes. Mas, neste caso, nenhum outro componente se preocupa com o contar estado, exceto para o Contador componente. Portanto, é melhor mover o estado para o Contador componente onde ele é realmente usado.

Movendo o estado para o componente filho

Quando você move o estado para o Contador componente, ficaria assim:

importar {useState} de'reagir'

funçãoContador() {
const [count, setCount] = useState(0)
retornar (


Então dentro do seu Aplicativo componente, você não precisa passar nada para o Contador componente:

// importa
funçãoAplicativo(){
retornar<Contador />
}

O contador funcionará exatamente da mesma forma que antes, mas a grande diferença é que todos os seus estados estão localmente dentro deste Contador componente. Portanto, se você precisar de outro contador na página inicial, terá dois contadores independentes. Cada contador é independente e cuida de todo o seu próprio estado.

Manipulando o estado em aplicativos mais complexos

Outra situação em que você usaria um estado global é com formulários. O Aplicativo componente abaixo passa os dados do formulário (e-mail e senha) e o método setter para o Forma de login componente.

importar { useState } de"reagir";
importar { Forma de login } de"./Forma de login";

funçãoAplicativo() {
const [formData, setFormData] = useState({
e-mail: "",
senha: "",
});

funçãoatualizarFormData(novos dados) {
setFormData((anterior) => {
retornar { ...anterior, ...novosdados };
});
}

funçãoao enviar() {
console.log (formData);
}

retornar (
data={formData}
updateData={updateFormData}
onSubmit={onSubmit}
/>
);
}

O Forma de login O componente recebe as informações de login e as processa. Quando você envia o formulário, ele chama o atualizarDados função que também é transmitida do componente pai.

funçãoForma de login({ onSubmit, data, updateData }) {
funçãomanipularEnviar(e) {
e.preventDefault();
onSubmit();
}

retornar (


Em vez de gerenciar o estado no componente pai, é melhor mover o estado para LoginForm.js, que é onde você usará o código. Isso torna cada componente independente e não dependente de outro componente (ou seja, o pai) para obter dados. Aqui está a versão modificada do Forma de login:

importar { useRef } de"reagir";

funçãoForma de login({ onSubmit }) {
const emailRef = useRef();
const senhaRef = useRef();

funçãomanipularEnviar(e) {
e.preventDefault();
onSubmit({
e-mail: emailRef.current.value,
senha: passwordRef.current.value,
});
}

retornar (


Aqui você vincula a entrada a uma variável usando ref atributos e o useRef React hook, em vez de passar os métodos de atualização diretamente. Isso ajuda a remover o código detalhado e otimize o desempenho do formulário usando o hook useRef.

No componente pai (App.js), você pode remover o estado global e atualizarFormData() método porque você não precisa mais dele. A única função que resta é onSubmit(), que você chama de dentro do Forma de login componente para registrar os detalhes de login no console.

funçãoAplicativo() {
funçãoao enviar(formData) {
console.log (formData);
}

retornar (
data={formData}
updateData={updateFormData}
onSubmit={onSubmit}
/>
);
}

Você não apenas tornou seu estado o mais local possível, mas também removeu a necessidade de qualquer estado (e usou referências em vez de). Então seu Aplicativo componente ficou significativamente mais simples (tendo apenas uma função).

Seu Forma de login O componente também ficou mais simples porque você não precisava se preocupar em atualizar o estado. Em vez disso, você apenas acompanha dois referências, e é isso.

Manipulando Estado Compartilhado

Há um problema com a abordagem de tentar tornar o estado o mais local possível. Muitas vezes, você se depara com cenários em que o componente pai não usa o estado, mas o passa para vários componentes.

Um exemplo é ter um TodoContainer componente pai com dois componentes filhos: Lista de afazeres e TodoCount.

funçãoTodoContainer() {
const [todos, setTodos] = useState([])

retornar (
<>


</>
)
}

Esses dois componentes filhos requerem o todos estado, então TodoContainer passa para os dois. Em cenários como esses, você deve tornar o estado o mais local possível. No exemplo acima, colocando-o dentro do TodosContainer é o mais local possível.

Se você colocasse esse estado em seu Aplicativo componente, não seria o mais local possível porque não é o pai mais próximo dos dois componentes que precisam dos dados.

Para grandes aplicações, gerenciar o estado apenas com o useState() gancho pode revelar-se difícil. Nesses casos, você pode precisar optar pelo API de contexto de reação ou Reagir Redux administrar o estado com eficácia.

Saiba mais sobre React Hooks

Hooks formam a base do React. Ao usar ganchos no React, você pode evitar escrever códigos longos que, de outra forma, usariam classes. O gancho useState() é indiscutivelmente o gancho React mais comumente usado, mas existem muitos outros, como useEffect(), useRef() e useContext().

Se você deseja se tornar proficiente no desenvolvimento de aplicativos com o React, precisa saber como usar esses ganchos em seu aplicativo.