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
![](https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4c5e1792-7bf2-4056-aaeb-a06363c75ac0_699x244.png)
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.