Introdução ao React Context - Como utilizar de forma simples
Tags: javascript, react, webdev, redux
Published: 2021-06-01 00:22:41

##Considerações
- Este é um artigo introdutório e apresenta uma forma de utilização do React Context. 
- É importante que você consulte as referencias para entender melhor os conceitos e quando se faz útil sua utilização.
-  O uso da context API exige ao menos os conhecimentos básicos do React (criação de componentes reutilizáveis, manipulação de estado, props...).

##O que é a Context API?
Se acessarmos a documentação do [React Context](https://reactjs.org/docs/context.html) teremos a seguinte definição:
>Context provides a way to pass data through the component tree without having to pass props down manually at every level.

A grosso modo temos o seguinte - *Context fornece uma maneira de passar dados entre componentes sem ter que passar manualmente em todos os níveis.*

**Mas o que isso significa?**
Os dados em React geralmente são passado para os componentes por meio de props, de pai para filho. Caso você tenha componentes que estejam aninhados de maneira mais complexa, pode ser complicado lidar com esses dados passando entre os componentes. E é ai que entra a Context API. De maneira bem simples, ao invés de acessar, por exemplo, um estado diretamente do componente ou passando através de props, você agora consegue acessar esse mesmo estado de forma global.


##Como utilizar?

Para melhor entendimento você pode acessar o código da explicação abaixo no [CodeSandbox](https://codesandbox.io/s/introducao-react-context-api-6er1g)

No exemplo abaixo nós teremos:
1. Um arquivo contendo toda a configuração da Context Api
3. Como recuperar os dados digitado no input em componentes diferentes
2. Dois componentes que serão atualizados com os valores digitados no input 

##Criando o contexto do usuário
No arquivo de contexto é onde criamos uma variável global que pode ser acessada em toda aplicação. O provedor do contexto é utilizado para envolver um componente pai e cada filho que existir na aplicação.

Para isso iremos criar o arquivo ``useContext.js`` que é onde vai ser criado a instancia do contexto e também as variáveis a serem utilizadas.

Em ``useContext.js``, crie o objeto de contexto importando e utilizando o ``createContext``

```js
import React, { createContext, useState } from "react";

export const MyContext = createContext();

export const UserProvider = ({ children }) => {
  const [nome, setNome] = useState("");
  const [sobrenome, setSobrenome] = useState("");

  return (
    <MyContext.Provider
      value={{
        nome,
        setNome,
        sobrenome,
        setSobrenome
      }}
    >
      {children}
    </MyContext.Provider>
  );
};
```
Acima exportamos o ``MyContext`` que vai ser utilizado nos componentes filhos. O ``useState`` para manter o estado das variáveis ``Nome`` e ``Sobrenome``, com seus métodos correspondentes.
Esses dados/variáveis são passados por meio do ``value`` do provedor. O provider serve para prover o context aos componentes filhos. 

##Envolvendo o componente App com o contexto criado

No arquivo ``index.js`` é feita a importação do ``UserProvider`` do arquivo de contexto ``useContext.js``. Com isso iremos envolver o ``<App/>`` com o ``UserProvider`` dessa forma:

```js
import ReactDOM from "react-dom";
import { UserProvider } from './useContext';

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <UserProvider>
    <App />
  </UserProvider>,
  rootElement
);
```

A partir desse momento todos os dados passados em ``value`` no nosso arquivo de contexto poderão ser acessados em outros componentes.

##Utilizando os dados Nome e Sobrenome

Para utilizar os dados nome e sobrenome, foi criado dois componentes ``nomeComponent.js`` e ``sobrenomeComponent.js``. Em ambos os arquivos é necessário importar o ``MyContext`` do nosso arquivo de contexto e o hook ``useContext`` que será utilizado para setar o contexto que vamos usar para acessar os dados disponibilizados. Ficando dessa forma:

####nomeComponent.js
```js
import React, { useContext } from "react";
import { MyContext } from "./useContext";

const Nome = () => {
  const usuario = useContext(MyContext);

  return (
    <div>
      <h2>
        <strong>Nome</strong>: {usuario.nome}
      </h2>
    </div>
  );
};

export default Nome;
```
####sobrenomeComponent.js
```js
import React, { useContext } from "react";
import { MyContext } from "./useContext";

const Sobrenome = () => {
  const usuario = useContext(MyContext);

  return (
    <div>
      <h2>
        <strong>Sobrenome</strong>: {usuario.sobrenome}
      </h2>
    </div>
  );
};

export default Sobrenome;
```

Perceba que, em ambos os componentes foi utilizado o código:
```js 
const usuario = useContext(MyContext);
```
A const ``usuario`` será a responsável para que possamos acessar as variáveis globais do nosso contexto.

##Atualizando os dados do contexto

No arquivo ``App.js``, importamos o ``MyContext`` e usando o hook ``useContext`` iremos consumir os dados do nosso contexto. Com os métodos ``setNome`` e ``setSobrenome`` recuperados do contexto, chamamos o ``onChange`` nos respectivos inputs para que os dados sejam atualizados a cada caractere digitado pelo usuário. Ficando dessa forma:

```js
import React, { useContext } from "react";
import { MyContext } from "./useContext";

import Nome from "./nomeComponent";
import Sobrenome from "./sobrenomeComponent";

import "./styles.css";

export default function App() {
  const usuario = useContext(MyContext);

  return (
    <div className="App">
      <div>
        <div>
          <label className="label">Nome: </label>
          <input
       onChange={(event) =>
       usuario.setNome(event.target.value)} />
        </div>
        <div>
          <label>Sobrenome: </label>
          <input 
       onChange={(event) =>
       usuario.setSobrenome(event.target.value)}
          />
        </div>
      </div>
      <Nome />
      <Sobrenome />
    </div>
  );
}
```

Com isso, toda vez que for detectada uma alteração em um dos inputs, ele vai acionar o método correspondente, que altera o valor no contexto, assim atualizando as informações em ``nomeComponent.js`` e ``sobrenomeComponent.js``.

##Conclusão

Neste artigo, usamos o React Context para criar variaveis globais e utiliza-las nos componentes sem precisar fazer uso de props.

##Referencias
[React Context](https://reactjs.org/docs/context.html)