Hooks - useState e useContext
Tags: javascript, webdev, beginners, react
Published: 2022-01-21 20:58:31

## [useState](https://pt-br.reactjs.org/docs/hooks-reference.html#usestate)

### O que é?

É uma função nativa do React adicionada na versão 16.8.0, popularmente conhecida como hook de estado. É uma funcionalidade recente, logo códigos legados normalmente ainda não a utilizam.

### O que faz?

Permite a criação e manipulação de estados dentro de componentes funcionais.

### Sintaxe

A sintaxe é muito simples, primeiro precisamos importar a função, em seguida, dentro do componente funcional, a chamamos passando como parâmetro o valor inicial do estado. Com isso podemos **atribuir** o retorno do `useState()` **a constantes**, essas que devem ser criadas **a partir da desconstrução de Array**.

É necessária essa desconstrução pelo fato de que a função `useState()` retorna um Array com dois valores, o primeiro é o valor do estado em si e o segundo é uma função que nos permite alterar aquele estado, podendo ser comparada a um _“setState exclusivo”_.

```jsx
import { useState } from 'react';

function SomeComponent() {
  const [myState, setMyState] = useState(<valor inicial>);
}
```

Por convenção o segundo valor do Array retornado do `useState()` deve ser nomeado da seguinte forma: set + nome do estado.

---

## [useContext](https://pt-br.reactjs.org/docs/hooks-reference.html#usecontext)

### O que é?

É uma função nativa do React adicionada na versão 16.8.0, popularmente conhecida como hook de contexto. É uma funcionalidade recente, logo códigos legados normalmente ainda não a utilizam.

### O que faz?

Essa função permite a utilização de contextos de forma mais simplificada e menos verbosa, porém por se tratar de um hook, seu uso é exclusivo em componentes funcionais.

### Sintaxe

Sua sintaxe se assemelha muito a do `useState()`, com a diferença que passamos o contexto por parâmetro no lugar no valor inicial. Outra diferença é a desconstrução dos valores, no `useContext()` **devemos desconstruir com base na estrutura passada no Provider**, se for um Array, desconstruimos um Array, se for um objeto, desconstruimos um objeto.

```jsx
import { useContext } from 'react';

const { someState, someHandler } = useContext(MyContext);
const [someState, setSomeState] = useContext(MyContext);
```

A utilização do `useContext()` substitui o `.Consumer`, porém a criação e estruturação do `.Provider` ainda é a mesma.

---

## Criando _"Contexto"_

### O que é?

O _“Contexto”_, **aqui em questão**, nada mais é do que um componente React que se preocupará única e exclusivamente com a parte lógica, sendo assim os estados, efeitos e até mesmo os _"handlers"_ de eventos, podem ficar agrupados no componente de _“Contexto”_.

### Sintaxe

Primeiro precisamos criar nosso _"Contexto"_, para isso utilizamos a função `createContext()` e armazenamos seu retorno a uma constante com nome adequado. Com o _"Contexto"_ criado, partimos para a definição do componente que irá armazenar nossa lógica.

Para criarmos tal componente utilizamos a sintaxe padrão de um componente funcional, uma função _(clássica ou arrow function)_ que irá conter funções e hooks próprios e retorna um código JSX. Com a diferença que nesse caso, nosso retorno será o `.Provider`, esse que irá renderizar os componentes que ele encapsular _(`props.children`)_.

```jsx
export const MyContext = createContext();

export function MyContextProvider() {
  const [someState, setSomeState] = useState(<valor inicial>)

  return (
    <MyContext.Provider value={{ someState, setSomeState }}>
      {props.children}
    </MyContext.Provider>
    )
}
```

```jsx
export const MyContext = createContext();

export const MyContextProvider = () => {
  const [someState, setSomeState] = useState(<valor inicial>)

  return (
    <MyContext.Provider value={{ someState, setSomeState }}>
      {props.children}
    </MyContext.Provider>
    )
}
```

---

## Usando “Contexto”

### O que é?

É a forma pela qual iremos acessar os estados, efeitos ou _"handlers"_ que definimos no componente de “Contexto”. _(explicado logo acima)_

### Sintaxe

O acesso a esses elementos é muito simples, primeiramente precisamos _“empacotar”_ os **componentes que estarão sobre o mesmo Contexto**. Feito isso, basta importar o _“Contexto”_ em si e salvá-lo dentro de uma constante através do hook `useContext()`.

```jsx
import MyContextProvider from './';

function App() {
  return (
    <MyContextProvider>
      <SomeComponent />
      <OtherComponent />
    </MyContextProvider>
  )
}
```

Logo acima temos o exemplo de encapsulação de componentes através do _"Componente Contexto"_ criado anteriormente na seção **Criando Contexto**.

E logo abaixo está o exemplo de como se consumir o contexto do `<MyContextProvider />` através do hook `useContext()`.

```jsx
function SomeComponent() {
  const { someState, setSomeState } = useContext(MyContext);

  return (
    <div>
      <p>{someState}</p>
      <button onClick={() => setSomeState()}>Click</button>
    </div>
  )
}
```

**Reforçando**, o `useContext()` recebe por parâmetro o Contexto que desejamos consumir e sua desestruturação deve respeitar a estrutura passada no `value={}` do `.Provider`.