ReactJS: entenda a diferença entre Function e Class component

A partir da versão 16.8 do ReactJS algumas atualizações foram implementadas, permitindo que a criação de componentes se tornasse mais fácil e menos verbosa. Neste artigo iremos abordar a diferença entre Function e Class component, para que você escolha qual se adapta melhor ao seu projeto.
Jessica Meira | 4 de junho de 2021

Que os Hooks do ReactJS não são mais novidade, já sabemos, mas eles ainda causam um pouco de espanto - principalmente se você está chegando agora e não entende o motivo de alguns componentes serem escritos com classe e outros com função. Se esse é o seu caso, assim como já foi o meu, pegue uma cadeira e sente-se confortavelmente que eu tentarei sanar as suas dúvidas.

Componentes

Para entender sobre a diferença entre componente funcional e componente de classe dentro do React, tenha em mente que componentes são os responsáveis por permitir a divisão da interface em partes independentes e reutilizáveis.

A maior diferença entre ambas as formas é a sintaxe. A utilização das funções é também mais reforçada devido ao código ser mais enxuto e a possibilidade de utilização dos hooks, ainda que haja funcionalidades específicas para os componentes de classe.

Componentes funcionais e componentes de classe

Não é difícil encontrar diversos projetos com componentes sendo criados a partir de classes, com a atualização do React para a versão 16.8, o padrão recomendado se tornou a function, já que nas versões anteriores os states não podiam ser utilizados em componentes funcionais. Dessa maneira, quando havia a necessidade de alteração ou de manipulação de algum state, era necessário que o componente fosse alterado para uma classe.

Vou mostrar como este processo era realizado anteriormente, e qual é a maneira recomendada hoje. Assim, você conseguirá ver na prática quais mudanças ocorreram.

Caso você queira testar os exemplos apresentados aqui, o projeto pode ser criado através do comando: npx create-react-app nomedoprojeto

Por padrão, as versões mais recentes criam a aplicação utilizando os modelos de função.

Componentes de classe

Antes, a sintaxe mais facilmente encontrada era algo parecido com essa:

import React from 'react';
class App extends React.Component {
  render() {
    return(
Olá,
    );}
}
export default App;

Agora, podemos criar um outro componente, a fim de reaproveitar o código. Veja:

import React from 'react';
class MyText extends React.Component{
  render(){
    return
Olá Pessoa/mundo
  }
}
class App extends React.Component {
  render() {
    return(
        
    );}
}export default App;

A nível de instrução, todo componente definido pelo usuário tem que, obrigatoriamente, começar com letra maiúscula.

O componente pode ser chamado várias vezes, sem problema nenhum. Aí, você me pergunta: “Por que eu iria chamar o mesmo componente várias vezes com o mesmo texto?” Que bom que você perguntou! Na verdade, eu só fiz isso para apresentar as props.

O que são props?

Segundo a própria documentação do ReactJS, as props ou propriedades são os parâmetros que você passa para o seu componente. Por exemplo:


Elas podem ter qualquer valor, exatamente como na função, quando eu invocar as props dentro do meu componente, será recebido tudo o que foi passado.

Dentro do componente as props são lidas assim:

return
Olá, {this.props.name}

O Exemplo ficará assim:

import React from 'react';
class MyText extends React.Component{
  render(){
    return
Olá, {this.props.name}
  }
}
class App extends React.Component {
  render() {
    return(
        
        
        
        
    );}
}
export default App;

Também é possível que esse meu componente aceite outros parâmetros vindos como props, exemplo:

import React from 'react';
class MyText extends React.Component{
  render(){
    return
Olá {this.props.local}! Eu sou uma {this.props.gender} chamada {this.props.name}
  }
}
class App extends React.Component {
  render() {
    return(
        
    );}
}
export default App;

Entendido o conceito das props, é importante saber que o há outro método utilizado em classe para cuidar dos states, ou seja, estados do meu componente.

States

Aqui começamos a entender como podemos alterar o valor ou estado das informações que temos no nosso componente. Este método é similar às props, porém privado.

Para explicar, trarei um exemplo um pouco diferente. Ao usar o this.state, como já mencionado anteriormente, é necessário que os componentes sejam declarados como classe, visto que estamos trabalhando desta forma podemos seguir adicionando o construtor na classe onde o estado do componente será alterado.

Conforme a documentação, o constructor é um método especial para criar e iniciar um objeto criado pela classe. Só pode existir um método com o nome constructor dentro da classe.

É importante entender que você não poderá utilizar o this em um construtor sem antes ter chamado o construtor pai. Isso é feito utilizando a palavra-chave super.

import React from 'react';
class MyText extends React.Component{
  render(){
    return
Clicado: {this.props.text}
  }
}
class MyButton extends React.Component{
  render(){
    return(
      {this.props.handleClick(this.props.button)} }>
      {this.props.button}
      
    )
  }
}
class App extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      mylabel: ""
    }
  }
  setMyLabel = (mylabel) => {
    this.setState({ mylabel });
  }
  render() {
    return(
        
        
        
    );}
}
export default App;

Entendendo o código:

  • Adicionado o construtor (constructor) e chamando o construtor pai (super) dentro da classe App;
  • No construtor é informado o valor inicial do elemento que será alterado através do this.state;
  • Declarado o método responsável por manipular o estado do nosso componente;

Partindo para a chamada desse método e renderização do componente, é passado o método responsável por atualizar o estado da mesma maneira que as props, ou seja, o nome e o valor, que no exemplo é: handleClick={this.setMyLabel} .

Dentro do componente MyButton será chamado a props que contêm este método, e também será passado como parâmetro o novo valor. Assim: onClick={() => {this.props.handleClick(this.props.button)} }>

Se você já está familiarizado com o React pode estar se perguntando sobre o ciclo de vida e seus métodos, mas isso podemos deixar para um próximo post. Que tal?

Até aqui entendido, de uma maneira mais direta e simples sobre a funcionalidade dos componentes de classe, vamos virar a chave e entender sobre outra maneira de declarar um componente.

Componentes de função

Nos componentes declarados como função temos algumas diferenças de sintaxe e os hooks, o que, atualmente, possibilita e facilita na sua usabilidade.

A base da função seria chamada dessa forma:

function App(props) {
  return (
Olá, {props.name}
  );
}
export default App;

Ou seja, utilizando as props sem problemas, porém sem mudança e manipulação através do this.state e sem a necessidade do método render.

Hooks

Eles permitem que você use o state e outros recursos sem criar uma classe para isso. As maravilhas da modernidade, não é mesmo?

As principais motivações para implantação dos hooks segundo o núcleo do React foram: A dificuldade em entender alguns componentes quando muito complexos e extensos, e a confusão para os novos desenvolvedores, onde a maneira de utilizar os estados acabava se tornando uma barreira no aprendizado do framework.

Caso você queira saber de maneira mais detalhada sobre o que levou a essa mudança, aqui tem um link super interessante.

Uma definição bem resumida encontrada na documentação é:

“Hooks são funções que permitem a você ‘ligar-se’ aos recursos de state e ciclo de vida do React a partir de componentes funcionais. Hooks não funcionam dentro de classes — eles permitem que você use React sem classes.”

Então, vamos de exemplo. Quando dizemos que atualmente os componentes se tornaram mais simples de se escrever, é devido a situações similares a esta:

import React, { useState } from 'react'
function App() {
  const [name, setName] = useState("Forasteiro");
  return (
Olá {name}
      setName("Viajante do tempo")}> 
      Click Me
      
  );
}
export default App;

Primeiro, há a importação do useState diretamente do React. Nós já entendemos que ele é um hook que nos permite manipular o state dentro de funções, mas o que ele faz?

Ele declara uma array onde o primeiro elemento manterá o estado inicial, que serve para preservar alguns valores entre as chamadas de função e o segundo elemento responsável por manipular os valores atuais.

A maneira como é informado o estado inicial da variável será informando-o como parâmetro para o useState().

Observando o exemplo, há a declaração de um array com dois valores, seguido do useState e um valor passado por parâmetro.

const [name, setName] = useState("Forasteiro")

O valor que está sendo passado por parâmetro será o valor inicial do estado. Ele será atribuído ao primeiro elemento dentro do array, ou seja, ao name. O segundo elemento setName será o responsável por alterar o estado do componente.

Para apresentar os valores que no nosso exemplo, caso fosse com classe seria this.state.name. Agora, com função é utilizado apenas o name diretamente.

A atualização desse estado também não poderia ser complicada, no caso do exemplo estamos lidando com um botão, então no click deste botão é chamado apenas o setName que irá atualizar o estado atual, passando por parâmetro qual será o novo valor.

Na prática, a diferença para o componente de classe, com o mesmo comportamento, seria assim:

import React from 'react';
class ExemploClasse extends React.Component {
  constructor(props){
    super(props)
    this.state = {
        name: "Forasteiro"
    }
  }
  render(){
    return (
Olá {this.state.name}
        this.setState({ name: "Viajante do tempo"})}> 
        Click Me
        
    );
  }
}
export default ExemploClasse

Ou seja, um pouco maior e consequentemente mais confuso para quem inicia no React.

Conclusão

Agora que ambas as formas foram apresentadas, fica a seu critério escolher a que faz mais sentido para você. Lembrando que até a publicação deste artigo o React não tem planos de descontinuar as classes, então você não precisa se preocupar, já que a inserção dos hooks aconteceu em fevereiro de 2019. Não é algo novo, mas ainda causa um pouco de confusão. Por esse motivo, o intuito deste artigo foi apenas apresentar as duas formas e demonstrar algumas diferenças entre elas.

Referências

  • Component and props
  • React: Getting Started
  • React Component
  • Hooks Reference
  • Hooks State
Jessica Meira
Software Engineer | Cursando pós-graduação em Inteligência Artificial, um pouco curiosa nas horas vagas. Mais de 15 anos na área de Tecnologia e apaixonada por música e instrumentos.