Aprenda utilizar Componentes Funcionais com React

A palavra “funcional” está bastante em alta no mundo da programação nos últimos tempos.
Poderíamos discutir por horas os motivos disso, porém não é o intuito desse artigo.
O React 0.14 trouxe uma forma mais simples de definir componentes utilizando plain JavaScript functions, chama-se functional stateless components.

Para começar, vamos criar um Hello World da forma que vínhamos fazendo antes do React 0.14:

import React from 'react';
import PropTypes from 'prop-types';

export default class HelloWorld extends React.Component{
  constructor(props){
    super(props);
  }

  sayHello(e){
    alert(`Hello ${this.props.name}`);
  }

  render(){
    return(
      <div>
        <a href="#"
          onClick={this.sayHello.bind(this)}>
          Say Hello!
        </a>
      </div>
    );
  }
}

HelloWorld.propTypes = {
  name: PropTypes.string.isRequired,
};

Basicamente, criamos um componente que tem uma propriedade chamada name e que renderiza um elemento de link que, quando clicado, exibe um alert com o valor dessa propriedade name, a ser definido quando esse componente for utilizado.

Agora, vamos ver como seria a declaração desse mesmo componente utilizando stateless functional components:


import React from 'react';
import PropTypes from 'prop-types';

const HelloWorld = ({ name }) => {
  const sayHello = (event) => {
    alert(`Hello ${name}`);
  }
  
  return(
    <a href="#" onClick={sayHello}>Say Hello</a>    
  );
}

HelloWorld.propTypes = {
  name: PropTypes.string.isRequired,
};

export default HelloWorld;

À primeira vista, já podemos notar um código muito mais limpo e menor comparando um código com o outro. O primeiro é mais verboso e possui 27 linhas, enquanto o segundo é mais limpo e possui 17 linhas. Não parece ser muita coisa, mas vamos comparar parte por parte.

Não precisa declarar nenhuma Class


export default class HelloWorld extends React.Component{
  constructor(props){
    super(props);
  } 

Para declarar um component, você não precisa declarar uma classe que estende a ‘React.Component’, mas sim utilizar apenas funções. E com ‘arrow functions’ a sintaxe fica ainda mais simples. Se você ainda não ouviu falar de ‘arrow function’, recomendo esse artigo: Arrow functions




const HelloWorld = ({ name }) => {
  const sayHello = (event) => {
    alert(`Hello ${name}`);
  }
  
  return(
    <a href="#" onClick={sayHello}>Say Hello</a>  
  );
}

export default HelloWorld;

Esqueça o this de vez!

Na minha opinião, isso pode ser muito bom e muito ruim. O uso do this não é mais necessário porque, ao usar ‘arrow function’, o ‘this’ realmente muda sem perder a referência. Dessa forma, basta apenas chamar a função ou a prop ou o state. Veja abaixo:



  return(
    <a href="#" onClick={sayHello}>Say Hello</a>  
  );
}

 <div>
    <a href="#"
       onClick={this.sayHello.bind(this)}>
          Say Hello!
    </a>
 </div>

Perceba que dispensamos também a necessidade do bind para poder passar o this. Como dito acima, isso já está implícito na chamada da função. A grande questão é que dessa forma podemos confundir onde o estado será realmente atualizado. O React mantém uma atualização de estados unilateral, o que significa que apenas componentes pai podem atualizar o estado, e componentes filhos tem apenas a permissão de ler o conteúdo do estado. O bind(this) serve para indicar que aquele é o componente pai daquele estado. Sem ele, teremos que ter atenção redobrada para não atualizar um estado em um componente filho.

Events Handlers

Para definir events handlers basta declará-los em linha como o exemplo acima. Porém, ao definir handlers dessa forma, a cada re-renderização do component a função de event handler será redefinida. Isso pode causar problemas de performance, principalmente, em aplicações maiores. Há duas formas para resolver esse problema. Você pode tirar o evento handler para fora da functional stateless component. Ou, você pode transformar o component em um full component:


  const sayHello = (event) => {
    alert(`Hello ${name}`);
  }

Performance

Essa é a principal vantagem de se usar FSC (e o meu argumento para te convencer a fazê-lo): o ganho em performance. No exemplo que utilizamos, o evento click teve duração de 0.15ms, enquanto com FSC teve duração de 0.08ms

Pode parecer uma pouca diferença, mas quando estamos falando de aplicações maiores, ou com foco em dispositivos móveis, cada ms (milisecond) conta para ganho de performance.

Considerações

A declaração de props, defaultProps e context continuam com a mesma sintaxe. o que muda em Functional Stateless Components, é a declaração dos components em si.

Se você não está tão acostumado com o paradigma funcional, talvez encontre uma certa dificuldade para se adaptar com FSC. Mas também não é nenhum “bicho de sete cabeças”. Então, é válido ao menos tentar.


BrazilJS é uma iniciativa NASC