Padrões de Projeto React

Boas práticas para o React

Veja neste artigo algumas das dicas e boas práticas para utilizar em uma aplicação React e tenha um código mais limpo na sua aplicação.

há 1 ano 5 meses


Você sabia que a TreinaWeb é a mais completa escola para desenvolvedores do mercado?

O que você encontrará aqui na TreinaWeb?

Conheça os nossos cursos

Quando falamos sobre boas práticas para o React, com certeza não estamos falando em uma prática recomendada universalmente que você possa aplicar a todos os negócios e aplicativos, mas para manter um aplicativo produtivo e flexível temos que seguir alguma boa prática para ter um bom código.

Neste artigo, vou esclarecer algumas regras que podem ser muito úteis ao criar sua aplicação utilizando React.

É bom ter o mínimo de conhecimento sobre a biblioteca React então você pôde conhecer mais sobre no artigo: Conheça o React, biblioteca para desenvolvimeto Web

React - Fundamentos
Curso React - Fundamentos
Conhecer o curso

Componentes funcionais

Existem duas formas de criarmos componentes React. Podemos criar via componentes de função e componentes de classe.

A utilização de componentes criados com classe existe uma certa complexidade, como a necessidade de um breve conhecimento em POO (programação orientado a objetos) e, também, pela sintaxe muito maior comparado a componentes criados com função, visto que um componente criado com função é simplesmente uma função que aceita props (objeto) como um argumento e retorna um elemento React (JSX).

Os componentes funcionais têm uma sintaxe muito simples. Você não precisa se preocupar com construtores e métodos de ciclo de vida. Sendo assim eles têm menos caracteres sem perder a legibilidade e você pode expressar a mesma lógica.

Segue um breve exemplo abaixo:

// má prática
class Counter extends React.Component{
	state = {
		counter:0
	}

	constructor(props){
		super(props)
		this.handleClick = this.handleClick.bind(this)
	}

	handleClick(){
		this.setState({counter:this.state.counter + 1})
	}

	render(){
		return (
			<div>
				<p>
					counter: {this.state.counter}
				</p>
				<button onClick={this.handleClick}>
					Increment
				</button>
			</div>
		)
	}
}

// boa prática
function Counter(){
	const [counter, setCounter] = useState(0)
	const handleClick = ()=>setCounter(counter +1)

		return (
			<div>
				<p>
					counter: {counter}
				</p>
				<button onClick={handleClick}>
					Increment
				</button>
			</div>
		)
}

Note que em ambos os componentes temos as mesmas funcionalidades e comportamentos, porém a sintaxe, no componente de classe, é um pouco maior e quem não tem um conhecimento em POO pode ficar um pouco perdido de como utilizá-lo.

Por isso, é uma boa prática criar componentes com funções em vez de classe.

Organização de funções auxiliares

Uma das boas práticas para o React é, não definir funções auxiliares dentro do próprio componente. O melhor lugar para definir funções auxiliares, e até mesmo a lógica do componente ou tela, é em hooks personalizados ou funções separadas do componente.

Você deve passar os valores do estado ou das funções auxiliares no retorno do hook e pode utilizá-lo desestruturando os dados do retorno do hook, para ter uma sintaxe um pouco menor.

// má pratica
function IndexComponent(props){
	function paseInt(value){
		return Number(value)
	}

	return (
		<div>
			{parseInt(props.data)}
		</div>
	)
}

// boa prática
function useIndex(){
	function paseInt(value){
		return Number(value)
	}
	return {parseInt}
}

function IndexComponent(props){
	const {parseInt} = useIndex()
	return (
		<div>
			{parseInt(props.data)}
		</div>
	)
}

Next.js - Fundamentos
Curso Next.js - Fundamentos
Conhecer o curso

Desestruturação das props

Como descrevi acima, componentes criados com funções são funções que recebem no parâmetro as props e retornam elemento React (JSX). Como as props são objetos nós podemos utilizar da desestruturação para ter um código mais limpo.

// má prática
function InputComponent(props){
	return (
		<button onClick={props.onClick}>
			{props.text}
		</button>
	)
}

// boa prática
function InputComponent({onClick,text}){
	return (
		<button onClick={onClick}>
			{text}
		</button>
	)
}

Quantidade de props

Outra pergunta muito comum é: “quantas propriedades passar em um componente?”. A resposta é muito simples, quanto mais props um componente recebe, mais motivos ele tem para se renderizar novamente, então você deve dar menos propriedades a um componente conforme for possível.

Prefira passar objetos em props

É muito comum criarmos componentes para passar propriedades e acabamos passando mais que o necessário.

Então, para evitar isso, em vez de passar propriedades que aceitam valores primitivos, como string e number, devemos passar objeto contendo todos os valores necessários para formar o componente. Fazendo isso, iremos seguir as boas práticas para o React

// má prática
<Perfil
	nome={user.nome}
	idade={user.idade}
	email={user.email}
	descricao={user.descricao}
/>

// boa prática
<Perfil
	user={user}
/>

Isso ajuda a diminuir o tamanho do código, visto que o próprio componente já deve tratar os dados internamente no componente.

Outra dica é utilizar TypeScript para facilitar a utilização de objetos nas propriedades do componente, visto que você consegue utilizar a tipagem para não cometer erros.

Evite ternários aninhados no JSX

Após o primeiro nível utilizando ternário no meio do JSX torna-se difícil ler os operadores, portanto, evite ao máximo possível o uso de operadores ternários aninhados.

Como opção para seguir boas práticas para o React, você pode utilizar as tomadas de decisão para melhorar a legibilidade do código.

// má prática
function Index(){
	const {data} = useIndex()

	return data ? (
		data.length === 0 ? (
		  <p>Nenhum elemento disponível</p>
		) : (
		  <>
			{data.map(({ nome }, i) => (
			  <p key={i}>{nome}</p>
			))}
		  </>
		)
	  ) : (
		<CircularProgress />
	);
}


// boa prática
function Callback({data, render}){
	if(data){
		if(data.length === 0){
			return <p>"Nenhum elemento disponível"</p>
		}
		return render(data)
	}
	return <CircularProgress />
}

function Index(){
	const {data} = useIndex()

	<Callback 
		data={data}
		render={(data)=>(
			<>
			 {data.map(({ nome }, i) => (
					  <p key={i}>{nome}</p>
					))}
			</>
		)}
	/>
}

Mapeamento de listas em componentes

No exemplo anterior utilizamos o método map para poder listar os valores que vieram de uma API de exemplo.

Fazer um loop sobre os itens da lista é um trabalho comum em nosso dia a dia e nós usamos o método map para esse propósito. Para listarmos tudo que é necessário sempre devemos criar um componente para fazer essa tarefa, visto que o método map cria alguns problemas de legibilidade. Se a propriedade for longa ou complicada, use um único mapeamento por componente.

// má prática
function Index(){
	const {data} = useIndex()

	<Callback
		data={data}
		render={(data)=>(
			<>
			 {data.map(({ nome }, i) => (
					  <p key={i}>{nome}</p>
					))}
			</>
		)}
	/>
}

// boa prática
function Index(){
	const {data} = useIndex()

	<Callback
		data={data}
		render={(data)=>(
			<PageName data={data}/>
		)}
	/>
}

function PageName({data}){
	return (
			<>
			 {data.map(({ nome }, i) => (
					  <p key={i}>{nome}</p>
					))}
			</>
		)
}

Use o caminho absoluto

Nos exemplos acima, criamos diversas funções para separar lógica e componentes, mas sabemos que quando estamos desenvolvendo uma tela podemos ter dezenas de importações de funções, objetos e componentes que vão ser necessários para finalizar a criação de uma tela.

Para ter uma melhor organização de código é interessante utilizar a importação absoluta de cada elemento.

import InputComponent from '@src/component/input/InputComponent'

Isso ajuda a ter um código mais limpo e caso você esteja utilizando TypeScript você pode configurar caminhos para ter a importação muito menor.

Outras soluções de importações que podemos utilizar é a seguinte. Imagine que temos uma importação comprida para acessar os nossos componentes como no exemplo abaixo:

import InputComponent from '@components/Input/InputComponent/InputComponent'

Mas o que realmente gostaria de escrever é o seguinte:

import InputComponent from '@components/Input/InputComponent'

Para resolver, você pode criar um index.js dentro da pasta InputComponent.

Estrutura de pastas componente react

Conclusão

Hoje tentamos entender da melhor forma possível como podemos ter um código mais limpo e organizado utilizando o React então vimos desde a teoria até uma pequena olhada em como funciona o código.

E ter um padrão que muda nossa forma de desenvolver é uma das mágicas dessa área maravilhosa de desenvolvimento.

Sempre teremos algo novo para ver, estudar, testar e aplicar no nosso dia a dia!

Agora, no seu projeto pessoal ou profissional, você terá mais confiança em construir seu código.

Caso queira aprender mais sobre o React, saiba que aqui na TreinaWeb nós temos a formação Desenvolvedor React - Funcional que possui 12h40 de vídeo e um total de 55 exercícios.

Veja quais são os cursos que fazem parte desta formação:

  • React - Fundamentos
  • React - Dominando Componentes Funcionais
  • React - Despertando o Poder dos Hooks
  • React - Conhecendo o React Router
  • React - Estilização com Emotion (Styled Components)

Autor(a) do artigo

Ariel Sardinha
Ariel Sardinha

Professor e desenvolvedor. Formando em engenharia de software e Computação - Licenciatura. É autor de cursos em diversos temas, como, desenvolvimento front-end, Flutter, JavaScript, React,js e Vue.js. Nas horas vagas adora estudar sobre tecnologia, filmes e brincar com a pequena Maria Eduarda. arielsardinha

Todos os artigos

Artigos relacionados Ver todos