Os novos front-ends contruidos com os frameworks mais atuais geraram por consequencia, maiores complexidades no que antes seria apenas construido com HTML+CSS+JS. Muitos termos e conhecimentos surgiram em conjunto com esses frameworks, e um deles é o estado da aplicação. Basicamente, cada componente que construímos possui em sí próprio uma base de dados em que ele se alimenta e escuta conforme suas modificações vão acontecendo.
O conceito de estado tomou sua devida complexidade quando foi necessário compartilhar o estado da aplicação de forma global entre os componentes de sua aplicação. Para isso, varias bibliotecas surgiram, como o Redux, MobEx e etc. O Redux, em teoria, seria a biblioteca mais utilizada para este fim entre os programadores React, e muitos deles acham sua usabilidade terrível.
O React context API é um gerenciador de estado global e é uma funcionalidade implementada a pouco tempo no ecosistema do React, podendo resolver 90% das soluções do Redux de forma extremamente simples.
Então, que tal aprendermos como utiliza-lo hoje? Vamos lá?
O que é um contexto?
O contexto, segundo o dicionário é definido como uma inter-relação de circunstâncias que acompanham um fato ou uma situação. A nossa situação no caso, seriam nosso componentes. Imagine que estamos em um carrinho de compras e esse carrinho precisa guardar o estado dos produtos anto na tela de carrinho quanto estiver com o carrinho aberto, quanto na página de listagem de produtos? Como resolveríamos isso?
Da forma antiga
Poderíamos criar vários componentes e passar os dados via props para cada componente. Assim, quando o componente de carrinho for renderizado, para cada clique de produto que o cliente deseje adicionar ao carrinho, deve-se chamar novamente o componente do carrinho, alterando suas props, e dentro do próprio carrinho, gerenciar todos esses dados que serão escutados por varios produtos diferentes na própria página...
Ufa! Só isso? Achou complexo?
Com o Context API
Utilizamos um contexto que engloba todos os componentes do app, e sempre que um produto for adicionado ao carrinho, o contexto será atualizado e notificará todos os componentes. Assim, nosso carrinho precisa apenas puxar as informações do contexto global da aplicação.
Simples né?
Uma imagem vale mais que mil palavras
Perceba que, sem a context, precisamos passar de forma encadeada, cada um dos dados, e sem ela, o contexto engloba todos os componentes de uma vez.
Vamos ao código?
Vamos construir um aplicativo de e-commerce através do create-react-app. Para isso, precisamos de um componente de carrinho e um componente de lista com os produtos. Precisamos que o estado se compartilhe entre os dois para que um saiba o que o outro sabe.
Criando o contexto
A primeira coisa que precisamos fazer é definir nosso contexto. Para isso, criamos ao lado do nosso arquivo de App.js um arquivo chamado AppContext.js. E importaremos, além de nossas depentencias comuns como useEffect e useState, a useContext e é ela que fará toda a mágica.
Para definir um contexto, usamos o useContext como mostrado abaixo:
import React, { useState, useEffect, createContext } from 'react';
export const AppContext = createContext();
Criando o estado
Com isso, criamos um contexto que englobará todo o App. Com o contexto criado, criaremos nele o estado do nosso carrinho através do useState:
export const Provider = (props) => {
const [cart, setCart] = useState([]);
}
Retornando o contexto
Por fim, com o estado criado, teremos agora que disponibilizar o estado para os componentes dentro do App. Fazemos isso com uma função de retorno da forma a seguir:
return (
<AppContext.Provider value={[drivers, setDrivers]}>
{props.children}
</AppContext.Provider>
)
Nosso arquivo AppContext.js ficará assim:
import React, { useState, useEffect, createContext } from 'react';
export const AppContext = createContext();
export const Provider = (props) => {
const [cart, setCart] = useState([]);
return (
<AppContext.Provider value={[drivers, setDrivers]}>
{props.children}
</AppContext.Provider>
)
}
E agora, o que precisamos?
Com nosso contexto criado, basta importa-lo no App.js e pronto, você já pode utiliza-lo. Veja abaixo como:
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import Routes from './routes';
import { Provider } from './AppContext'
function App() {
return (
<Provider>
<BrowserRouter>
<Routes />
</BrowserRouter>
</Provider>
);
}
export default App;
Assumindo que nosso componentes se encontram no Router Dom, automaticamente com o Provider, podemos fazer com que eles escutem o estado global.
E como eu chamo o estado no meu componente?
Vamos imaginar que estamos no componente Cart.js. O que faremos para chamar o contexto do estado? Apenas, inserir o código abaixo:
import React, { useContext } from 'react'
import { AppContext } from '../../AppContext'
export default function Cart() {
const [cart, setCart] = useContext(AppContext)
}
Pronto! Nosso Cart já pode utilizar as funções que utilizaria normalmente em seu estado interno. Cada vez que você chamar setCart() todo o App escutará essas mudanças, sem necessidade de Reducers, nem Actions, nem Dispatch, nem nada disso. Simples não?
Lembre-se que você pode ter inúmeros contextos dentro de uma mesma aplicação.
Obrigado por mais uma leitura!
Top comments (0)