Os Pilares do React

18 de agosto, 2020 — 5 min read

Os Pilares do React

O que é o React?

React é uma biblioteca do Javascript desenvolvida pelo Facebook para criação de interfaces baseadas em componentes, criada por Jordan Walke.

O React segue uma maneira declarativa de programar, encapsulando as lógicas em componentes específicos para cada parte da aplicação.

O foco deste post é introduzir os pilares necessários para desenvolver suas primeira aplicações com esse framework. Entendendo o conceito e como utilizar esses pilares já é possível utilizar grande parte dos recursos do React.

Introdução ao JSX

Considere esse o primeiro componente da aplicação:

import React from 'react'

function App() {
  return (
    <div className="App">
      <h1>Hello ReactJS</h1>
    </div>
  )
}

export default App

Essa declaração estranha de tags não é uma string, muito menos HTML comum.

No início pode parece estranho, por que juntar HTML com o código JavaScript? Logo veremos que essa forma faz sentido e facilita na hora de desenvolver dentro do React, pois a lógica fica encapsulada no próprio componente.

JSX é uma extensão de sintaxe para o Javascript (JavaScript eXtension) baseado em XML(sintaxe do HTML). Lembrando que o navegador não entende essa sintaxe então deve ser transpilado utilizando por exemplo o Babel, que transforma o JSX em código Javascript.

O código transpilado para criar uma div vazia seria algo do tipo:

React.createElement('div', null)

Componentes

Quando trabalhamos com React utilizamos o conceito de componentização, ou seja, dividimos a UI em partes independentes, reutilizáveis e permitindo pensar em cada parte isoladamente.

Antigamente utilizávamos componentes de classe para trabalhar com estados mas hoje utilizamos somente componentes funcionais graças a “nova” API de hooks.

import React from 'react'

export default function Person() {
  return <h1>O nome da pessoa é: André Zagatti</h1>
}

Essa função é um componente de React válido porque não está recebendo nenhum parâmetro(pode receber as propriedades como já vamos ver) e retorna um elemento JSX do React. Esses componentes são chamados de componentes funcionais, pois são literalmente funções do Javascript. Um detalhe, sempre que utilizarmos a sintaxe de JSX devemos importar o React.

import React from 'react'

import Person from './components/Person'

function App() {
  return <Person />
}

export default App

Como vimos antes o React entende as tags do HTML no JSX mas também podemos utilizar nossos próprios componentes como tags.

Propriedades (props)

As props dos componentes do React se assemelham a atributos passados para tags do HTML.

import React from 'react'

export default function Person(props) {
  return <h1>O nome da pessoa é: {props.name}</h1>
}

Agora o componente Person não fica preso a um nome estático e pode ser reutilizado simplesmente passando outro nome para as props.

import React from 'react'

import Person from './components/Person'

function App() {
  return (
    <div>
      <Person name="Solaire of Astora" />
      <Person name="Andre of Astora" />
      <Person name="Sigmeyer of Catarina" />
    </div>
  )
}

export default App

Quando passamos dados utilizando as props de um componente temos que passar exatamente o nome que será usado dentro do componente como o nome da prop. Essa passagem de dados nomeados é normalmente chamada de Named/Labeled Arguments, com os objetos do JavaScript é muito fácil utilizar esse modelo.

Estado

O estado do componente é uma variável que armazena informações atuais do componente, caso haja uma alteração o componente e seus componentes filhos serão renderizados novamente(acontece o mesmo com as props).

Para utilizarmos o estado em componentes funcionais utilizamos a “nova” API do React chamada de hooks. O hook de estado se chama useState, que é uma função que recebe o estado inicial e retorna um array sendo a primeira posição o valor do estado e a segunda uma função para atualizar esse valor seguindo os conceitos da imutabilidade.

import React, { useState } from 'react'

import Person from './components/Person'

function App() {
  const [name, setName] = useState('')
  /**
   * É o mesmo que
   * const nameState = useState('');
   * const name = nameState[0];
   * const setName = nameState[1];
   */

  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <Person name={name} />
    </div>
  )
}

export default App

Nesse componente estamos utilizando os pilares do estado e de props.

Detalhando melhor o que o componente está fazendo, o [name, setName] é uma desestruturação de array disponível no Javascript desde o ES6 onde o name referencia o primeiro elemento do array e o setName o segundo.

No input a propriedade value é necessária para o valor exibido em tela do input refletir com o valor do state name. Sobre o onChange é um evento do input que disparada a cada nova letra digitada nele, o que é passado é o evento de mudança, então para pegarmos o valor digitado e inserir no state de name utilizando e.target.value.

No componente de Person podemos ver que não está sendo mais passada uma string e sim uma variável do Javascript, então para inserir Javascript dentro do JSX utilizamos as chaves. É interessante de se notar que podemos compartilhar o estado de um elemento pai para um elemento filho, que é uma coisa muito utilizada. Podemos também compartilhar o estado de um elemento filho para o pai mas é algo mais complexo e nem sempre necessário.

Hook de Efeito (useEffect)

Quando utilizávamos componentes de classe era comum utilizarmos os métodos de ciclo de vida do componente. Esses métodos ficavam responsáveis por executar funções e alterar dados quando o componente montava, era alterado ou era desmontado. Hoje com a API de hooks utilizamos um único hook para tratar esses casos, chamado de useEffect.

import React, { useState, useEffect } from 'react'

function App() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    const interval = setInterval(() => setCount(count + 1), 1000)

    return () => {
      clearInterval(interval)
    }
  }, [count])

  return (
    <div>
      <h1>{count} segundos</h1>
    </div>
  )
}

export default App

O useEffect recebe como primeiro parâmetro uma função de callback com o código que será executado quando o componente for montado, o segundo parâmetro é o array de dependências do hook de efeito, esse array de dependências são as variáveis externas utilizadas dentro dele e que ele observará, quando acontecer uma alteração nessas variáveis ele executará novamente.

Como tem uma alteração no state do componente todo segundo por conta do setInterval é necessário passar uma callback de retorno do useEffect para que ele consiga limpar o Interval quando o componente for desmontado, se essa callback de retorno não for passada acontecerá efeitos colaterais na aplicação de vários Interval’s estarão rodando ao mesmo tempo causando vazamento de memória e alterando o state repetidas vezes.

Existe uma sintaxe alternativa de utilização da função de alterar o estado que pode eliminar essa repetida execução do useEffect(que causa muitos loops) retirando o count do array de dependências.

import React, { useState, useEffect } from 'react'

function App() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    setInterval(() => setCount((state) => state + 1), 1000)
  }, [])

  return (
    <div>
      <h1>{count} segundos</h1>
    </div>
  )
}

export default App

Utilizando um callback para alterar o estado é possível recuperar o valor atual do estado e utilizando ele já para criar um novo. Mas como funções como Interval podem ficar rodando em background sem que percebamos recomendo deixar o return limpando o Interval como precaução.

Bônus

Como bônus resolvi colocar como fazer uma chamada a API. Para isso usaremos o hook de efeito e a API nativa para requests HTTP chamada fetch.

import React, { useEffect } from 'react'

export default function App() {
  useEffect(() => {
    ;(async () => {
      const response = await fetch('https://api.github.com/users/azagatti')
      const data = await response.json()
      console.log(data)
    })()
  }, [])

  return (
    <div>
      <h2>Fetch data!</h2>
    </div>
  )
}

Algumas coisas interessantes de se notar, não é possível usar diretamente o async no useEffect, então normalmente seria possível usar a sintaxe de Promise com then mas podemos utilizar uma IIFE (Immediately invoked function expression) para escrever com a sintaxe de async e await.

O que fazer em seguida? Normalmente armazenaríamos esse data retornado da API num estado e realizaríamos um map no JSX para mostrar os dados que quisermos, até poderíamos criar novos componente que recebam por props esses dados e fiquem com a responsabilidade de exibir os valores.

Conclusão

Nesse post abordei o que considero os pilares para o desenvolvimento utilizando o React, entendendo como aplicar cada um deles já é possível desenvolver utilizando esse framework, mas isso é só o começo, existem mais conceitos, outros hooks e várias bibliotecas utilizadas no ecossistema do React que valem ser estudadas. Como por exemplo biblioteca para criação de rotas na página, trabalhar com formulários, referências dos elementos e muito mais.

Para quem quiser testar os códigos facilmente sem criar todo o ambiente, pode utilizar o código mostrado no post no Codesandbox, só comentar e tirar os comentários do que quiser: https://codesandbox.io/s/pensive-cache-cwohe

Fontes:

https://reactjs.org/ ou https://pt-br.reactjs.org/

https://www.youtube.com/watch?v=dpw9EHDh2bM


Se inscreva para novidades:

Para mais informações, acesse:Política de Privacidade

Enviar
A. Zagatti Logo

André Zagatti

Engenheiro de software frontend que gosta de compartilhar conhecimento.

© 2023, André Zagatti