Uma foto minha vestido com o uniforme da Grifinória do Harry Potter

Willian JustenSoftware Engineer

Instrutor na Udemy, escrevo sobre o mundo front end, viagens, vida pessoal e mais.

← Voltar na listagem

#3 - O básico da API do ReactJS

Aprenda um pouco mais sobre a API do React e como começar a brincar.

Introdução

Para animar um pouco, a trilha sonora escolhida é o novo cd do Tame Impala - Currents, aproveitando que lançou essa semana.

Como prometido, vou dar continuidade a série de posts sobre ReactJS e para acompanhar tanto essa série, como outras, é só ir no link series.

Nos posts anteriores eu falei um pouco do que é o React e as formas de utilizá-lo em um projeto, agora eu irei mostrar e explicar um pouco da API do React para podermos começar a brincadeira.

Tentarei não fazer um post grande e cansativo, portanto, irei separar os conceitos básicos e no decorrer dos outros posts, onde iremos criar mini aplicações, a gente vai pegando mais coisas.

Criando e Renderizando componentes

O primeiro de tudo é saber como podemos criar os componentes e como renderizá-los. Para isso, irei demonstrar com um simples Hello World, mas lembre-se que isso poderiam ser componentes de qualquer forma.

ReactDOM.render

render(
  ReactElement element,
  DOMElement container,
  [function callback]
)

update: (02/06/2016) - O método anteriormente ficava dentro da API do React, mas agora passou para a API específica do ReactDOM.

O método render é um dos métodos mais importantes do React e que será responsável por renderizar elementos. Ele recebe 3 parâmetros, que são o elemento a ser criado, o local onde será inserido no DOM e uma função de callback, que é chamada logo após a renderização.

Um detalhe importante aqui é que, caso o elemento já exista no DOM, o render somente irá atualizar as partes novas no DOM, seguindo o algoritmo de diff, comentado no primeiro post.

Segue um vídeo em inglês, explicando este método.

Render sem JSX - React.createElement

ReactDOM.render(
  React.createElement('h1', null, 'Hello World!'),
  document.getElementById('content')
)

Sem o JSX, não temos como adicionar tags html dentro do nosso render, portanto, precisamos criar esses elementos na mão. Para criar, utilizamos o método createElement, que recebe 3 parâmetros também. O primeiro parâmetro é a tag html, o segundo é um objeto, que fica responsável pelo conjunto de informações, que podem ser classes, ids, data, estilos, etc.

Segue um vídeo em inglês, falando sobre este método.

Render com JSX

ReactDOM.render(<h1>Hello World!</h1>, document.getElementById('content'))

Para o render com o JSX, basta criamos o elemento com as tags do próprio html e ligarmos a um container.

createReactClass

createReactClass(object specification)

Serve para criar um componente dada uma especificação. Um componente implementa um método render que retorna um filho único. Esse filho pode ter uma estrutura arbitrária. A vantagem deste método é que nos permite já criar componentes para serem reaproveitados.

var Hello = createReactClass({
  render: function () {
    return <h1>Hello World!</h1>
  }
})

ReactDOM.render(<Hello />, document.getElementById('content'))

Como podemos notar, com a utilização do createReactClass, habilitamos um componente com o nome da variável determinada, no nosso caso Hello e então podemos chamá-lo em diversos lugares como <Hello />, conforme indicado na linha 10.

Segue um vídeo em inglês, explicando como funciona.

React.component (ES6)

No ES6, nós ganhamos classes para o nosso lindo javascript e, com isso, conseguimos extender métodos para essa classe, permitindo também a criação de componentes reutilizáveis, conforme o exemplo a seguir:

class Hello extends React.Component {
  render() {
    return <h1>Hello World!</h1>
  }
}

ReactDOM.render(<Hello />, document.getElementById('content'))

Exemplos

Seguem os exemplos rodando no Codepen:

See the Pen by Willian Justen de Vasconcellos (@willianjusten) on CodePen.

Repare que eu criei diferentes containers para que cada elemento fosse renderizado em um desses espaços.

Usando JS dentro do render

Já que é tudo JS, podemos usar o próprio JS para brincar dentro do render, como, por exemplo, receber um array e iterar nele para poder renderizar uma lista.

var frutas = ['Banana', 'Maçã', 'Uva']

ReactDOM.render(
  <div>
    {frutas.map(function (fruta) {
      return <li>{fruta}</li>
    })}
  </div>,
  document.getElementById('compras')
)

See the Pen by Willian Justen de Vasconcellos (@willianjusten) on CodePen.

No exemplo, eu tenho um array frutas e através do comando map, eu itero e mando retornar fruta por fruta dentro de uma lista com o id compras.

Props

Quando utilizamos nossos componentes no React, nós podemos adicionar atributos a eles, dos quais chamamos de props. Esses atributos ficam disponíveis para nosso componente através do this.props e podem ser usados no método de render para renderizar dados dinâmicos, de acordo com o quisermos passar.

var Hello = createReactClass({
  render: function () {
    return <h1>Hello {this.props.name}!</h1>
  }
})

ReactDOM.render(<Hello name="Willian" />, document.getElementById('hello'))

Olhando no exemplo, notamos que ele recebe o nome da variável name e consegue renderizar o nome corretamente.

See the Pen by Willian Justen de Vasconcellos (@willianjusten) on CodePen.

Especificações, Ciclos de Vida e Estado

Especificações (Specs)

Quando criamos um elemento e utilizamos o render, ele irá procurar pelas propriedades (this.props) e estado (this.state) daquele elemento. Se você precisar interagir com essas informações, existem alguns métodos para isso.

getInitialState

Esse método é chamado uma só vez antes de renderizar e ele servirá para definir um valor para o this.state do elemento, para que ele possa ser utilizado depois.

getInitialProps

Esse método é chamado uma só vez antes de renderizar e ele servirá para definir um valor para o this.props do elemento, para que ele possa ser utilizado depois.

propTypes

O objeto de propTypes permite validar as propriedades que estão sendo passadas para os componentes.

Ciclos de Vida (Lifetime Cycles)

O método de render é responsável por pegar as informações e renderizar na tela, mas existem outros ciclos que podem existir dentro dessa renderização, que são:

  • componentWillMount: chamado uma vez só, tanto do lado client quando do server antes da renderização acontecer.
  • componentDidMount: chamado uma vez só, só na parte do cliente, depois da renderização.
  • shouldComponentUpdate: chamado depois da renderização quando as propriedades e o estado está sendo definido. Ele retorna true ou false para dizer se o elemento deve atualizar.
  • componentWillUnmount: chamado quando desejamos desmontar o componente.

Existem mais métodos na API, basta dar uma olhada aqui.

Criando um timer

Já tendo os conceitos acima, conseguimos criar um simples timer. Segue o código e vamos destrinchá-lo:

var Timer = createReactClass({
  getInitialState: function () {
    return { elapsed: 0 }
  },

  componentDidMount: function () {
    this.timer = setInterval(this.tick, 50)
  },

  componentWillUnmount: function () {
    clearInterval(this.timer)
  },

  tick: function () {
    this.setState({ elapsed: new Date() - this.props.start })
  },

  render: function () {
    var elapsed = Math.round(this.state.elapsed / 100)
    var seconds = (elapsed / 10).toFixed(1)

    return (
      <p>
        Já se passaram <b>{seconds}</b> segundos.
      </p>
    )
  }
})

ReactDOM.render(<Timer start={Date.now()} />, document.getElementById('timer'))

Na linha 3, usamos o método getInitialState para poder definir que o estado inicial é quando elapsed vale 0, ou seja, não passou o tempo ainda.

Na linha 7, estamos usando o componentDidMount que será chamado assim que o elemento for renderizado na página, setamos aqui o setInterval para que ele fique chamando o método tick para ficar atualizando o tempo durante esse intervalo.

Na linha 11, colocamos o componentWillUnmount para dizer que se por algum motivo o componente for removido da tela, ele ativar aquele evento, que nada mais é que limpar o interval, já que não iremos mais atualizar nada na tela.

A linha 15 é onde criamos uma função de auxílio, que servirá para ir definindo o estado do meu componente, que nada mais é que o tempo que já passou. Para isso, utilizamos o método setState. Repare que utilizamos o seguinte trecho this.props.start, isso significa que estamos passando para o nosso componente uma propriedade com o nome start (guarde isso, por enquanto).

Na linha 25 estamos basicamente fazendo a etapa de renderização com o render, onde usamos a variável seconds que é definida na linha 21 usando como parte do cálculo o estado do componente, que é setado por this.state.elapsed.

Por fim, na linha 31 estamos chamando o nosso componente Timer e passando a tal propriedade start, que seria o tempo de agora, para que ele possa iniciar a contagem do tempo.

Segue um exemplo live no Codepen:

See the Pen by Willian Justen de Vasconcellos (@willianjusten) on CodePen.

O legal é que o React irá modificar somente o elemento que está com estado sendo modificado, ou seja, somente o que está dentro de <b>{seconds}</b>, o resto da frase permanecerá intacta, com isso, impacta menos o DOM.

Conclusão

Bom, esses são os principais métodos do React e com eles já conseguimos fazer bastante coisa, se quiser se aprofundar, vale dar uma olhada na documentação. Durante a elaboração dos códigos, eu foquei somente nas possibilidades do React e não no JS em si, caso você ainda não se sinta confortável com algumas das coisas feitas acima, aconselho que volte um pouco e estude mais de JS, para que possa desenvolver melhor. Lembrando que é sempre mais importante saber a linguagem do que uma biblioteca.

Ahhh, mas como eu aprendo mais de Javascript?

Tem um curso do Fernando Daciuk que é foda para caramba e vai te ensinar a realmente virar um Ninja no JS, se quiser saber mais do curso, basta ir nesse link. Pode parecer propaganda, mas não é, o curso é realmente bom e é realmente importante entender a linguagem antes de partir mais para frente. Mas qualquer dúvida, é claro que você pode falar nos comentários abaixo!!

Veja mais posts

Série sobre React