Header Ads

Como usar contextos de reação para gerenciar o estado

Contextos de reação são um recurso que o ajuda a eliminar perfurações repetitivas. Os adereços são freqüentemente passados ​​de um componente pai para um filho profundamente aninhado. Isso requer que cada componente intermediário “ encaminhe ” o suporte para o próximo componente na árvore.

Os contextos permitem que você passe adereços pela árvore sem encaminhá-los manualmente em cada nível. Isso é particularmente útil para dados que representam o estado do aplicativo de nível superior. As configurações do usuário, tokens de autenticação e dados armazenados em cache das respostas da API são bons candidatos para a API Context.

Esses dados são geralmente gerenciados por um armazenamento de estado dedicado, como Redux. Os contextos do React podem ser usados ​​em seu lugar. Isso remove uma quantidade significativa de complexidade nos aplicativos em que o Redux é usado apenas para manter o estado no nível do aplicativo. Em vez de criar uma ação, despachante e redutor, você pode usar um contexto React.

Um exemplo sem contexto

Depois que um usuário faz login, você geralmente deseja armazenar dados essenciais, como nome e endereço de e-mail, no estado do seu aplicativo. Isso permite que cada componente exiba informações sobre o usuário sem fazer uma viagem de ida e volta para o servidor de API.

Esta é uma maneira ingênua de implementar isso:

const UserProfileLink = & # 40; & # 123; user & # 125; & # 41; = > & # 123; return & # 40; < div > < p > Conectado como & # 123; usuário. Nome & # 125; < / p > < a href = " / logoff " > Logoff < / a > < / div > & # 41 ;; & # 125 ;;   const Header = & # 40; & # 123; user & # 125; & # 41; = > & # 123; return & # 40; < div > < h1 > My App < / h1 > < UserProfileLink user = & # 123; usuário & # 125; / > < / div > & # 41 ;; & # 125;   const App = & # 40; & # 41; = > & # 123; const & # 91; user, setUser & # 93; = useState & # 40; & # 123; Nome: " Foo Bar & quot ;, Email: " foobar@example. com" & # 125; & # 41 ;; return < Header user = & # 123; user & # 125; / > & # 125;

Existem três componentes no aplicativo. O componente App de nível superior rastreia o usuário atual em seu estado. Ele renderiza o componente Header. O cabeçalho renderiza UserProfileLink, que exibe o nome do usuário.

Crucialmente, apenas UserProfileLink realmente interage com o objeto de usuário. O cabeçalho ainda precisa receber uma proposta do usuário. Isso é então encaminhado diretamente para o UserProfileLink, sem ser consumido pelo Header.

Os problemas com esta abordagem são exasperados conforme sua árvore de componentes se torna mais complexa. Você pode encaminhar adereços por meio de vários níveis aninhados, mesmo que os componentes intermediários não usem os próprios adereços.

Adicionando a API Contexts

Você pode atenuar esses problemas usando a API Contexts. Podemos refatorar o exemplo acima para remover a proposta do usuário do cabeçalho.

O componente App criará um novo contexto para armazenar o objeto do usuário atual. UserProfileLink consumirá o contexto. O componente será capaz de acessar os dados do usuário fornecidos pelo contexto. Este é um conceito semelhante a conectar um componente a uma loja Redux.

const UserContext = React. createContext & # 40; null & # 41 ;;   const UserProfileLink = & # 40; & # 41; = > & # 123; const user = useContext & # 40; UserContext & # 41 ;; return & # 40; < div > < p > Conectado como & # 123; usuário . Nome & # 125; < / p > < a href = " / logoff " > Logoff < / a > < / div > & # 41 ;; & # 125 ;;   const Header = & # 40; & # 41; = > & # 123; return & # 40; < div > < h1 > Meu aplicativo < / h1 > < UserProfileLink / > < / div > & # 41 ;; & # 125;   const App = & # 40; & # 41; = > & # 123;   const & # 91; user, setUser & # 93; = useState & # 40; & # 123; Nome: " Foo Bar & quot ;, Email: " foobar@example. com" & # 125; & # 41 ;;   retornar & # 40; < UserContext. Provider value = & # 123; user & # 125; > < Header / > < / UserContext > & # 41 ;;   & # 125;

Este conjunto refatorado de componentes ilustra como usar contextos.

O processo começa criando um novo contexto para o valor que você deseja disponibilizar. A chamada para React. createContext (null) configura um novo contexto com um valor padrão de null.

O componente do aplicativo foi reescrito para envolver o cabeçalho em UserContext. Provider. O valor prop determina o valor atual do contexto. Isso é definido para o objeto de usuário mantido no estado. Todos os componentes aninhados abaixo do provedor de contexto agora podem consumir o contexto e acessar o objeto de usuário.

Se você tentar acessar o contexto de um componente que não está aninhado em uma instância do provedor, o componente receberá o valor padrão que você passou para createContext (). Isso geralmente deve ser evitado, exceto para valores de contexto estáticos que nunca serão alterados.

O acesso ao valor de contexto fornecido é observado em UserProfileLink. O objeto do usuário foi removido. O componente usa o gancho useContext () do React para recuperar o valor atual do UserContext. Isso fornecerá o objeto de usuário injetado pelo componente App!

A alteração final é no componente Cabeçalho. Isso não precisa mais encaminhar o objeto do usuário para que ele possa ser removido por completo. Na verdade, o objeto do usuário desapareceu de todo o aplicativo. Agora é alimentado pelo App no ​​provedor UserContext, não por qualquer componente específico.

Usando contexto com componentes de classe

Até agora, usamos apenas contextos em componentes funcionais. Os contextos funcionam bem aqui, pois o gancho useContext () simplifica o acesso aos dados fornecidos nos componentes filhos.

Você também pode usar contextos com componentes de classe. A maneira preferida é definir a propriedade da classe contextType estática para a instância de contexto que você deseja usar. O React lerá essa propriedade e definirá a propriedade do contexto nas instâncias do componente para o valor atual fornecido pelo contexto.

const UserContext = React. createContext & # 40; & # 123; Nome: " Foo Bar " & # 125; & # 41 ;;   a classe MyComponent estende React. Component & # 123;   // Diz ao React para injetar o valor `UserContext` contextType = UserContext;   renderizar & # 40; & # 41; & # 123; // Valor de contexto solicitado disponibilizado como `this. context`retorno < p > & # 123; this. context. Name & # 125; < / p & gt ;; & # 125 ;   & # 125;

Uma abordagem alternativa é renderizar os filhos do seu componente dentro de um contexto de consumidor. Você pode acessar o consumidor de cada contexto como a propriedade Consumer da instância do contexto.

Você deve fornecer uma função como filho do consumidor. A função será chamada com o valor do contexto quando o componente for renderizado.

Esta é a aparência disso:

const UserContext = React. createContext & # 40; & # 123; Nome: " Foo Bar " & # 125; & # 41 ;;   a classe MyComponent estende React. Component & # 123;   renderizar & # 40; & # 41; & # 123; return & # 40; < UserContext. Consumer > & # 123; user = > < p > & # 123; user. Name & # 125; < / p > & # 125; < /UserContext. Consumer> & # 41 ;; & # 125;   & # 125;

Usar contextType restringe você a um contexto por componente. Os consumidores de contexto resolvem esse problema, mas podem tornar o método de renderização do seu componente mais opaco. Nenhuma das abordagens é tão direta quanto o gancho useContext () disponível para componentes funcionais.

Atualizando valores de contexto

Os valores de contexto funcionam de forma semelhante aos adereços. Se um filho precisa atualizar os valores de contexto, adicione uma função ao contexto. A criança pode chamar a função para efetuar a alteração do valor do contexto.

const UserContext = React. createContext & # 40; null & # 41 ;;   const UserProfileLink = & # 40; & # 41; = > & # 123; const context = useContext & # 40; UserContext & # 41 ;; return & # 40; < div > < p > Conectado como & # 123; contexto . user. Name & # 125; < / p > < a onClick = & # 123; & # 40; & # 41; = > context. logoutUser & # 40; & # 41; & # 125; > Sair < / a > < / div > & # 41 ;; & # 125 ;;   const Header = & # 40; & # 41; = > & # 123; return & # 40; < div > < h1 > Meu aplicativo < / h1 > < UserProfileLink / > < / div > & # 41 ;; & # 125;   const App = & # 40; & # 41; = > & # 123;   const & # 91; user, setUser & # 93; = useState & # 40; & # 123; Nome: " Foo Bar & quot ;, Email: " foobar@example. com" & # 125; & # 41 ;;   const contextValue = & # 123; usuário, logoutUser: & # 40; & # 41; = > setUser & # 40; null & # 41; & # 125;   return & # 40; < UserContext. Provider value = & # 123; contextValue & # 125; > < Header / > < / UserContext > & # 41 ;;   & # 125;

Este exemplo revisado mostra como o App agora fornece uma função logoutUser dentro do contexto. Os consumidores de contexto podem chamar esta função para atualizar o usuário no estado do componente do aplicativo, fazendo com que o valor do contexto seja modificado de acordo.

Gerenciamento de re-renderizadores

O React irá renderizar novamente todos os filhos de um provedor de contexto sempre que a proposta de valor do provedor mudar. As alterações de valor são comparadas usando Object. is (), o que significa que você deve tomar cuidado ao usar objetos como o valor do provedor de contexto.

const App = & # 40; & # 41; = > & # 123; return & # 40; < ExampleContext. Provider value = & # 123; & # 123; foo: " bar " & # 125; & # 125; > < NestedComponent />);}

Este componente renderizará novamente o NestedComponent sempre que o App for renderizado. Uma nova instância de objeto é criada para a proposta de valor do provedor a cada vez, então o React renderiza novamente os filhos do componente.

Você pode resolver isso elevando o objeto de valor para o estado do componente. Isso garantirá que o mesmo objeto seja renderizado todas as vezes:

const App = & # 40; & # 41; = > & # 123; const & # 91; obj, setObj & # 93; = useState & # 40; & # 123; foo: " bar " & # 125; & # 41 ;; return & # 40; < ExampleContext. Provider value = & # 123; obj & # 125; > < NestedComponent />);}

Resumo

Os contextos do React ajudam a eliminar o detalhamento do suporte, fornecendo uma maneira de primeira classe de passar dados para baixo na árvore de componentes. Contextos são uma boa alternativa para bibliotecas de estado como Redux. Eles são integrados ao React e estão ganhando força entre os projetos em que o Redux é usado exclusivamente para conectar componentes profundamente aninhados a uma fonte de estado compartilhada.

Os contextos destinam-se a “ global ” dados mantidos em seu aplicativo. Eles também podem conter dados para uma subseção específica do seu aplicativo. Os contextos não pretendem substituir totalmente o estado do componente local. Os componentes individuais devem continuar a usar o estado e os adereços em que os dados só vão passar para cima e para baixo em uma árvore aninhada superficialmente.

Nenhum comentário