Introdução ao React.JS

O React.JS é uma biblioteca JavaScript do Facebook para construir interfaces de usuário, em tradução livre.

Diferentemente do Backbone.JS, AngularJS, Ember e outros que fornecem todos os componentes necessários para uma aplicação front-end, o React se preocupa apenas com a parte de view.

Isso quer dizer que ele não assume nada em relação ao seu stack e não fornece nenhuma camada de service, controller, model, collection, routes e etc.

O React trabalha apenas com o conceito de componente que recebe propriedades, computa o estado e retorna uma representação virtual do DOM.

Isso quer dizer que componentes do React não trabalham com templates propriamente ditas, como Handlebars.js ou Hogan.js.

A forma como ele lida com isso é estruturando a representação do HTML em objetos.

Imagine o seguinte código JavaScript:

function Element (name, content) {  
  this.name = name;
  this.content = content;
}

var el = new Element("p", "Você ainda não curtiu isso.");  

Agora imagine que você tenha dois elementos representando o momento 1 e o momento 2 do seu componente:

var m1 = new Element("p", "Você ainda não curtiu isso.");  
var m2 = new Element("p", "Você curtiu isso.");  

Qual a diferença entre os dois? Apenas o content mudou.

Aqui entra a grande sacada do React: se o resultado do seu componente mudou de m1 para m2, ele não removerá o elemento antigo e inserir o novo, ele simplesmente aplicará o diff.

Você pode imaginar isso como:

// Primeiro momento do componente
var el = document.createElement("p");  
el.innerHTML = "Você ainda não curtiu isso.";

document.body.appendChild(el);

// Segundo momento do componente
el.innerHTML = "Você curtiu isso.";  

A única diferença entre os dois momentos é o innerHTML então o React simplesmente altera ele no elemento que já estava anexado ao DOM.

Isso reduz o tempo de processamento em ordens de magnitude quando comparado (não necesseriamente nesse exemplo simples mas imagine em aplicações reais onde atributos, eventos e conteúdo são alterados em centenas de nodes) com:

// Primeiro momento do componente
var el = document.createElement("p");  
el.innerHTML = "Você ainda não curtiu isso.";

document.body.appendChild(el);

// Segundo momento do componente
el.parentNode.removeChild(el);

el = document.createElement("ul");  
el.innerHTML = "Você curtiu isso.";

document.body.appendChild(el);  

Isso é feito de uma forma tão simples quanto no React:

var LikeButton = React.createClass({  
  render: function () {
    return React.createElement(
      "p",
      null,
      "Você ainda não curtiu isso."
    );
  }
});

React.render(  
  React.createElement(LikeButton, null),
  document.body
);

Tudo o que seu componente precisa implementar é uma propriedade render que retorna o VDOM do seu componente.

Você deve ter notado que é bem verboso escrever o seu componente dessa maneira e é pensando nisso que o Facebook criou o JSX:

var LikeButton = React.createClass({  
  render: function () {
    return (
      <p>Você ainda não curtiu isso.</p>
    );
  }
});

React.render(  
  <LikeButton />,
  document.body
);

O JSX é um transpiler que simplesmente compila esse segundo código no primeiro.

Ele faz isso parseando o XML do seu JavaScript e convertendo ele para instruções do React, nada demais apesar de assustar em um primeiro momento.

Agora para conseguirmos fazer algo dinâmico com o componente precisamos entender o que são props e state no React.

A forma mais simples de entender a diferença entre os dois é que props é tudo aquilo que vem de fora do seu componente e não pode ser mutado, enquanto state é literalmente o estado do seu componente e pode ser mutado.

Observação: Você até pode copiar as propriedades para o estado e a partir daí mutar o estado mas isso é considerado uma anti-pattern por duplicar a "source of truth". Porém existe uma exceção, mais detalhes aqui.

Entenda que sempre que o estado do componente for mutado o render será chamado novamente e realizado aquele diff que expliquei no começo para atualizar todas as diferenças no DOM.

Para entender como tudo funciona podemos usar um exemplo parecido com o que consta na documentação aqui:

var LikeButton = React.createClass({  
  getInitialState: function () {
    return {liked: false};
  },

  handleClick: function () {
    this.setState({liked: !this.state.liked});
  },

  render: function () {
    var text = this.state.liked ? 'curtiu' : 'ainda não curtiu';

    return (
      <p onClick={this.handleClick}>
        Você {text} isso, {this.props.name}.
      </p>
    );
  }
});

React.render(  
  <LikeButton name="Gabriel Sobrinho" />,
  document.body
);

Observação: todas os métodos são bindados ao próprio componente pelo React quando instanciado para economizar CPU e evitar ter sempre que bindar os callbacks usando o this.method.bind(this), mais informações aqui.

Ao renderizar esse componente e clicar no texto, o estado do componente será alterado indicando ao React para re-computar o VDOM e atualizar o DOM.

Note que como o this.props.name veio de fora do componente, ele não pode ser alterado, mas o this.props.like pode ser alterado por se tratar de algo interno.

Com esse exemplo é possível ver o básico do React funcionando: JSX, Component, VDOM, State, Props e Events.

A documentação do React é bem interessante mas acabo sempre me perdendo nela, acredito que seja por ela ser um pouco densa.

Publicarei em breve outros artigos sobre o React e outros frameworks, acompanhem o feed!