React
A teoria de operação do React é baseada em princípios fundamentais que permitem a construção de interfaces de usuário de forma eficiente e reativa. Abaixo estão os principais conceitos e mecanismos que sustentam o funcionamento do React.
Teoria de Operação do React
1. Componentes
Os componentes são a base da arquitetura do React. Eles permitem dividir a interface em partes menores e reutilizáveis. Existem dois tipos principais de componentes:
- Componentes Funcionais: São funções JavaScript que retornam elementos React. Com a introdução dos Hooks, eles podem gerenciar estado e efeitos colaterais.
function MeuComponente() {
return <div>Olá, mundo!</div>;
}
- Componentes de Classe: Usam a sintaxe de classe do JavaScript e podem ter métodos de ciclo de vida. Embora ainda sejam suportados, seu uso está diminuindo em favor dos componentes funcionais.
class MeuComponente extends React.Component {
render() {
return <div>Olá, mundo!</div>;
}
}
2. JSX (JavaScript XML)
JSX é uma sintaxe que permite escrever HTML dentro de arquivos JavaScript. Ele facilita a criação de elementos React e torna o código mais legível.
const elemento = <h1>Meu Título</h1>;
3. Props (Propriedades)
As props são um mecanismo para passar dados de componentes pais para componentes filhos. Elas são imutáveis e ajudam a criar componentes que podem ser reutilizados em diferentes contextos.
function Saudacao(props) {
return <h1>Olá, {props.nome}!</h1>;
}
// Uso
<Saudacao nome="Maria" />
4. State (Estado)
O state é um objeto que armazena dados que podem mudar ao longo do ciclo de vida de um componente. Alterações no estado acionam re-renderizações do componente e de seus filhos.
import React, { useState } from 'react';
function Contador() {
const [contagem, setContagem] = useState(0);
return (
<div>
<p>Contagem: {contagem}</p>
<button onClick={() => setContagem(contagem + 1)}>Incrementar</button>
</div>
);
}
5. Ciclo de Vida dos Componentes
Os componentes têm um ciclo de vida que abrange várias fases, como montagem, atualização e desmontagem. Os componentes de classe têm métodos específicos (como componentDidMount, componentDidUpdate, e componentWillUnmount) que permitem a execução de código em diferentes momentos do ciclo de vida. Nos componentes funcionais, os Hooks, como useEffect, desempenham um papel semelhante.
6. Renderização
A renderização no React é um processo eficiente. Quando o estado ou as props de um componente mudam, o React re-renderiza esse componente e seus filhos. O React utiliza um algoritmo de reconciliação para determinar quais partes da árvore de componentes precisam ser atualizadas, minimizando o número de operações diretas no DOM.
7. Virtual DOM
O React utiliza um conceito chamado Virtual DOM, que é uma representação leve do DOM real. Quando há uma mudança no estado ou nas props, o React faz uma atualização no Virtual DOM. Em seguida, ele compara o Virtual DOM com o DOM real e calcula a diferença (diffing). Apenas as partes que mudaram são atualizadas no DOM real, o que melhora o desempenho.
8. Hooks
Os Hooks são funções que permitem que componentes funcionais tenham acesso a recursos de estado e efeitos colaterais. Exemplos de Hooks incluem useState, useEffect, useContext, entre outros.
import React, { useState, useEffect } from 'react';
function Exemplo() {
const [contador, setContador] = useState(0);
useEffect(() => {
console.log(`O contador é: ${contador}`);
}, [contador]);
return <button onClick={() => setContador(contador + 1)}>Incrementar</button>;
}
TDD - Vitest (Testing Library)
O teste com testing library facilita fazer testes desacoplados da implementação, ele simula o comportamento real do componente e lhe permite usar uma interface que simula cliques e lê conteúdo da tela de acordo com o comportamento esperado do componente
// UserManager.test.jsx
import { render, fireEvent, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import UserManager from './UserManager'; // Importando o componente
describe('UserManager', () => {
it('deve permitir que o usuário adicione um gerente e exibi-lo na lista', async () => {
render(<UserManager />);
// Passo 1: Interagir com o combobox
const input = screen.getByRole('combobox');
fireEvent.change(input, { target: { value: 'Gerente A' } });
// Passo 2: Verificar se as sugestões aparecem
const suggestion = await screen.findByText('Gerente A');
expect(suggestion).toBeInTheDocument();
// Passo 3: Selecionar o gerente
fireEvent.click(suggestion);
// Passo 4: Verificar se o gerente selecionado aparece na lista
const selectedManager = screen.getByText('Gerente A');
expect(selectedManager).toBeInTheDocument();
});
});