Tornado variáveis globais em react-native com context.
Tags: javascript, reactnative, react, braziliandevs
Published: 2024-03-05 19:06:56

Ao fim do artigo você saberá como usar Context em seu app react-native para fazer com que suas variáveis/estados sejam globais, ou seja, acessíveis de todas as telas.

## Problema

Eu estou desenvolvendo um app que usa dados locais e os armazena em SQLite e preciso que após buscar esses dados eles estejam disponíveis em várias telas. Além disso é necessário que após atualizar o banco eu consiga atualizar os dados disponíveis em todas as telas.

## Criando um context e um provider.

Primeiro eu crio uma pasta para os contexts, nesse caso vai ser apenas um, chamada 'contexts', após isso o arquivo que será declarado o context e o provider, como os dados que eu quero que sejam globais são dados do banco de dados local, chamei o arquivo de Data.jsx ficando:

src/contexts/Data.jsx

do heact eu importo a função '[createContext](https://react.dev/reference/react/createContext)'

Um básico ficaria assim:

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

export const dataContext = createContext({})

function DataProvider({children}){
    const [item, setItem] = useState([])
    return(
        <dataContext.Provider value={{ item }}>
            {children}
        </dataContext.Provider>
        )
}

export default DataProvider;
```

Assim todas as telas conseguirão acessar o state 'item', vou mostrar o meu exemplo real aqui:

```
import { useState, createContext, useEffect} from "react";
import { getSubjects } from "../storage/subjectRepository";
import { initDB } from "../storage/db";

export const dataContext = createContext({})

function DataProvider({children}){
    const [listSubject, setListSubject] = useState([])
    useEffect(()=>{
        // Inicializa o banco de dados criando as tabelas
        initDB()

        // Busca as disciplinas no banco de dados depois um tempo
        // para dar tempo das tabelas serem criadas se for a primeira
        // vez que o user abre o app
        setTimeout(()=>{
            getSubjects( subjects => {
                //Define o estado de listSubject o resultado da consulta
                setListSubject(subjects)
                console.log("my subjects:", subjects)
            })
        }, 500)  
        
    },[])

    return(
        <dataContext.Provider value={{ listSubject, setListSubject }}>
            {children}
        </dataContext.Provider>
        )
}

export default DataProvider;
```

Nessa forma é possível tornar disponível para todas as telas os dados do banco de dados.

```
return(
    <dataContext.Provider value={{ listSubject, setListSubject }}>
            {children}
    </dataContext.Provider>
)
```
É Importante destacar que nessa parte que são passados os dados que estarão disponíveis, estes dentro do objeto em value.

## Encapsulamento de contexto

Para o provider funcionar é necessário fazer um "encapsulamento" dos componentes de tela com o provider

```
export default function App(){
    return(
    <NavigationContainer>
      <DataProvider>
        <MyTabs></MyTabs>
      </DataProvider>
    </NavigationContainer>
    )
}
```
Dessa forma todos os componentes que estiverem encapsulados pelo provider poderão consumir os dados passados, no exemplo acima todas as telas estão em <MyTabs> assim todas elas têm acesso aos dados.

## Consumo de contexto

Para consumir esses dados do contexto é necessário importar o [useContext](https://react.dev/reference/react/useContext) e o contexto criado.

```
import { useContext } from "react"
import { dataContext } from "../../contexts/Data"

```
E dentro do componente que se deseja consumir esse contexto, usa-se a desestruturação para pegar apenas as variáveis que se deseja:

```
const {listSubject, setListSubject} = useContext(dataContext)
```

Dessa forma, com states dentro de um componente podemos usar a função set do useState para modificar o valor o state e também usar esse valor para exibir na tela ou fazer qualquer manipulação.

Assim é possível tornar globais variáveis e states. 

## Referências
[Sujeito Programador - Entender Context API](https://www.youtube.com/watch?v=olSeMN70Vo4)
https://react.dev/reference/react/createContext
https://react.dev/reference/react/useContext