Aguarde...

2 de agosto de 2021

Primeiros passos com React useContext Hook e React Context

Primeiros passos com React useContext Hook e React Context

O contexto React facilita a criação de dados e estados acessíveis globalmente. O gancho useContext permite que você trabalhe com contextos React de qualquer lugar e passe seus dados por todo o aplicativo. Este tutorial mostrará como criar um novo contexto, como obter valores a partir dele e como alterá-los.

Contexto de reação, estados globais, perfuração de suporte

Quando você trabalha com dados, eles geralmente são de dois tipos, globais ou locais. Global pode ser acessado de qualquer lugar. Local apenas a partir do local onde são definidos e descendo na árvore. Isso também se aplica a estados. Você pode ter estados globais e pode ter estados locais. Qual é a melhor escolha depende da situação.

A API de contexto React facilita a criação desses estados globais. Dito isso, há um problema com esses estados globais. Eles geralmente são difíceis de usar em componentes aninhados. Ele pode ter um monte de perfuração prop para obter os dados de cima para onde você precisar deles. Você pode ter que passar esses dados por vários componentes.

Uma maneira de resolver isso é tornar esses dados locais. No entanto, isso levaria à duplicação do código. Também iria contra a ideia de ter uma fonte da verdade que seja globalmente acessível. Outra solução é pular todas as perfurações de suporte e simplesmente acessar o contexto do componente em que você precisa desses dados.

Este é o objetivo do gancho React useContext. O gancho React useContext promete ajudá-lo em duas coisas. Primeiro, para ajudá-lo a alcançar qualquer contexto e de qualquer lugar. Em segundo lugar, trabalhar com valores expostos neste contexto. Isso inclui tanto obter esses valores quanto alterá-los. Vamos dar uma olhada em como isso funciona.

O contexto

Usar o contexto React requer poucas coisas. Primeiro, você deve criar um contexto. Você consegue isso usando o createContext()método enviado com o React. Este contexto será o estado global disponível para uso no aplicativo. Bem, pelo menos um deles, porque seu aplicativo React pode conter um número infinito de contextos.

// context.jsx

// Import createContext() method from React:
import { createContext } from 'react'

// Create new context:
export const newContext = createContext()

Observe que estamos declarando o contexto como vazio, basicamente atribuindo-o undefined. Não se preocupe. Isso não significa que este contexto ficará vazio para sempre. Ele estará vazio por enquanto, quando você o criar. Posteriormente, na próxima etapa, você adicionará valores a ele. Observe também que estamos exportando o contexto.

A razão para isso é simples. O gancho useContext aceita um contexto como parâmetro. Portanto, se quisermos usar o gancho useContext para acessar o contexto em qualquer lugar do aplicativo, o próprio contexto também deve estar acessível em qualquer lugar. Isso significa que devemos exportá-lo de onde ele está.

O provedor de contexto

A segunda coisa que você precisa fazer é criar um provedor para seu novo contexto. Este provedor é um componente que fornece ao seu aplicativo os valores armazenados dentro do contexto. O provedor envolve todos os componentes que devem ser capazes de acessar o contexto. É importante lembrar isso.

Os componentes poderão se comunicar com o provedor apenas se forem filhos do provedor. Não importa onde eles estejam na árvore de componentes. O que importa é que o provedor seja usado como um invólucro em algum lugar da árvore acima. Em geral, o provedor é usado como um wrapper para todo o aplicativo.

Isso garante que qualquer componente do aplicativo será capaz de se comunicar com o provedor. Se você tiver vários provedores, pode agrupar um dentro do outro enquanto mantém o aplicativo como o último filho. Isso garantirá que o aplicativo tenha acesso a todos os provedores na árvore. Agora, vamos criar o provedor.

Criação do provedor de contexto

Criar o provedor é semelhante a criar um componente React normal. Hoje em dia, o provedor geralmente é criado como um componente de função. Você dá a este componente algum nome. É uma boa prática terminar o nome com “Provedor”. Isso torna mais fácil entender o código quando você o lê.

Dentro desse componente, você pode usar qualquer gancho de reação que desejar. Por exemplo, você pode usar o gancho useState para criar um novo estado para o provedor. Você pode então expor esse estado definindo-o como um valor para o provedor. Isso o tornará disponível para qualquer componente empacotado com o provedor.

Você também pode usar o gancho useCallback para criar funções memoized. Essas funções podem trabalhar com o estado, atualizar seus valores. Você também pode expor essas funções definindo-as como valores para o provedor. Novamente, isso os tornará disponíveis para componentes agrupados com o provedor.

A parte mais importante é onde acontece a renderização, o que segue a returndeclaração. Aqui, você usará o contexto pela primeira vez. O contexto que você criou anteriormente também contém um componente de provedor que seu novo provedor renderizará. Você pode acessar este componente de provedor usando notação de ponto de objeto ( newContext.Provider).

Como queremos usar esse provedor como um wrapper, ele deve renderizar todos os filhos que envolver.

// context.jsx

// Import createContext() method from React:
import { createContext } from 'react'

// Create new context:
export const newContext = createContext()

// Create new provider component:
export const NewProvider = (props) => {
  return (
    {/* Render Provider provided by previously created context: */}
    <newContext.Provider>
      {/* Render Provider's children: */}
      {props.children}
    </newContext.Provider>
  )
}

Certifique-se de também exportar seu novo componente Provedor para que você possa usá-lo onde precisar. A próxima etapa é pegar o Provedor e usá-lo como um wrapper para os componentes para os quais você deseja tornar os dados fornecidos por esse provedor acessíveis. Você também pode usá-lo para envolver o componente principal do aplicativo.

Isso tornará qualquer coisa exposta pelo provedor acessível a qualquer componente do aplicativo.

// index.jsx

// Import React and React-dom:
import { StrictMode } from 'react'
import ReactDOM from 'react-dom'

// Import the NewProvider component:
import { NewProvider } from './context'

// Import app component:
import App from './App'

// Create the main component:
const rootElement = document.getElementById('root')
ReactDOM.render(
  <StrictMode>
    {/* Use the NewProvider to wrap the whole app: */}
    <NewProvider>
      {/* The app component rendering all other components: */}
      <App />
    </NewProvider>
  </StrictMode>,
  rootElement
)

Adicionando estado ao provedor de contexto

O próprio provedor é inútil se não fornecer nenhum valor, ou valores, ao aplicativo. Para consertar isso, você precisa de duas coisas. Primeiro, você precisa de algum valor, de alguns dados que deseja disponibilizar por meio do provedor. Em segundo lugar, você deve tornar esses dados acessíveis a partir do provedor.

O primeiro pode ser corrigido criando um novo estado local dentro do provedor. O gancho useState será perfeito para isso. O valor desse estado será o que você deseja compartilhar no aplicativo. Como o gancho useState também cria uma função de atualização, isso também fornecerá uma maneira de atualizar esse estado compartilhado.

Para consertar a segunda coisa, você deve adicionar um valueatributo ao myContext.Providercomponente retornado pelo NewProvidercomponente. O valor deste atributo pode ser qualquer coisa, desde um tipo de dado primitivo até um objeto. Se você deseja compartilhar um único valor, o primeiro será suficiente.

Se você quiser compartilhar vários valores, ou valores e funções, será melhor usar um objeto. É bom disponibilizar valores em todo o aplicativo. Melhor ainda é permitir também a alteração desses valores em todo o aplicativo. Então, vamos com o objeto. Vamos criar um novo estado e expor ambos, o estado e sua função de atualização por meio do provedor.

// context.jsx

// Import createContext() method and useState hook from React:
import { createContext, useState } from 'react'

// Create new context:
export const newContext = createContext()

// Create new provider component:
export const NewProvider = (props) => {
  // Create local state:
  const [state, setState] = useState('')

  // Prepare values to share:
  const val = {
    state, // The state itself
    setState // The state update function
  }

  return (
    {/* Set "val" as the value for "value" attribute: */}
    <newContext.Provider value={value}>
      {props.children}
    </newContext.Provider>
  )
}

Acessando o contexto com o gancho useContext

Você está quase pronto. Você tem contexto, tem provedor e tem algo para compartilhar por meio do provedor. Você também empacotou o aplicativo com o provedor e expôs algum valor por meio do valueatributo do Provedor . Agora você pode acessar o estado e a função setState exposta por meio do provedor em qualquer lugar no aplicativo.

Para conseguir isso, você precisa de apenas duas coisas. A primeira coisa é o gancho React useContext. A segunda coisa é o contexto exportado, aquele que você criou no início com o createContext()método. Ao combinar esses dois, você terá acesso imediato ao statesetStatevocê criou no NewProvidercomponente.

Vamos criar o Appcomponente principal . Você viu este componente no index.jsxarquivo como o filho direto do provedor (seção Criando o provedor de contexto). Este componente será simples. Ele conterá dois componentes: título mostrando mensagem de boas-vindas e valor atual de statee entrada para atualizar o statevia setState.

Você obterá ambos, statesetState, do newContextcontexto. Lembre-se de que este contexto é fornecido pelo NewProvidercomponente. Você obterá esses valores chamando o gancho React useContext e passando o newContextcontexto como um argumento.

// Import useContext hook from React:
import { useContext } from 'react'

// Import newContext context:
import { newContext } from './context'

// Create the App component:
export default function App() {
  // Access the state and setState values in newContext:
  const { state, setState } = useContext(newContext)

  return (
    <div>
      {/* Display the value of "state" */}
      <h1>Hello {state}</h1>

      <h2>Change name:</h2>
      {/*
        Use "setState" update function to update the current value
        of "state" with the current value of input:
      */}
      <input type="text" onChange={(e) => setState(e.target.value)} />
    </div>
  )
}

Múltiplos contextos

Basicamente, não há limite para quantos contextos e provedores você pode ter em seu aplicativo React. Você pode ter quantos quiser, contanto que se lembre de adicionar cada provedor como um wrapper. Por exemplo, podemos adicionar contexto adicional para e-mail a este aplicativo de amostra simples. Isso exigirá um novo contexto e um novo componente Provedor.

Primeiro, vamos criar um novo contexto para o e-mail. Isso será quase uma cópia espelhada do contexto que você já possui. Você mudará principalmente apenas os nomes.

// email-context.jsx

// Import createContext() method from React:
import { createContext, useState } from 'react'

// Create new context:
export const emailContext = createContext()

// Create new email provider component:
export const EmailProvider = (props) => {
  // Create local state for email:
  const [email, setEmail] = useState('')

  // Prepare values for sharing:
  const val = {
    email,
    setEmail,
  }

  // Render emailContext.Provider exposing "val" variable:
  return (
    <emailContext.Provider value={val}>
      {/* Render children components: */}
      {props.children}
    </emailContext.Provider>
  )
}

Em seguida, você deve importar o contexto de e-mail no arquivo principal, onde renderiza o Apppara o elemento raiz. Quando você tem vários fornecedores, o pedido deles realmente não importa. É importante que o aplicativo, ou algum componente onde você deseja usar os dados desses provedores, seja empacotado com esses provedores.

import { StrictMode } from 'react'
import ReactDOM from 'react-dom'

import { NewProvider } from './context'

// Import new email provider:
import { EmailProvider } from './email-context'

import App from './App'

const rootElement = document.getElementById('root')
ReactDOM.render(
  <StrictMode>
    {/* Add email provider as another wrapper of the App component: */}
    <EmailProvider>
      <NewProvider>
        <App />
      </NewProvider>
    </EmailProvider>
  </StrictMode>,
  rootElement
)

Com isso, agora você pode usar o gancho React useContext com emailContextpara acessar o emailsetEmailem qualquer lugar no aplicativo.

import { useContext } from 'react'

import { newContext } from './context'

// Import new email context:
import { emailContext } from './email-context'

export default function App() {
  const { state, setState } = useContext(newContext)

  // Access the email and setEmail values in emailContext:
  const { email, setEmail } = useContext(emailContext)

  return (
    <div>
      {/* Render the value of "email": */}
      <h1>
        Hello {state}, {email}
      </h1>

      <h2>Change name:</h2>
      <input type="text" onChange={(e) => setState(e.target.value)} />

      <h2>Change email:</h2>
      {/*
        Allow to to update the current value of "email"
        via the "setEmail" update function and text input:
      */}
      <input type="text" onChange={(e) => setEmail(e.target.value)} />
    </div>
  )
}

Conclusão: Introdução ao React useContext hook and react context

Criar estados globais com o contexto React é muito fácil. Com a ajuda do gancho React useContext, também é fácil acessar esses contextos e seus dados. Espero que este tutorial tenha ajudado você a entender como criar contextos e seus provedores e como usar o gancho useContext para se comunicar com eles.

Postado em Blog
Escreva um comentário