5 Bibliotecas Essenciais para Desenvolver React Apps
O conjunto de ferramentas, boilerplates e bibliotecas disponíveis formam um ecossistema incrível em torno do React.
No meio de tudo, existem ferramentas que são comuns – e essenciais – a diversas aplicações, independente de suas arquiteturas. Cito cinco delas.
1. classnames
Muitas vezes, no React, um estado representará um comportamento visual do componente (“selecionado”, “pressionado”, “focado”), normalmente associado a uma classe CSS.
Um botão e seus estados disabled e hovered, por exemplo, ficariam assim:
<button
type="submit"
onMouseOver={...}
className={classNames('button', this.props.className, {
'button--disabled': this.state.isDisabled,
'button--hovered': this.state.isHovered
})}
/>
Perceba que o Classnames facilita a manipulação condicional de classes com React, removendo vários blocos de if
/else
do seu código.
2. react-router
Se você está desenvolvendo uma Single-page Application, você precisará sincronizar a interface do usuário com a URL.
O React Router é a melhor solução de rotas para aplicações desenvolvidas com React, e isso se deve bastante a sua API declarativa e pensada para componentes.
Considere a seguinte configuração de rotas:
import React from "react";
import { render } from "react-dom";
import { Router, Route, browserHistory } from "react-router";
import App from "components/App";
import Homepage from "screens/Homepage";
import About from "screens/About";
import Contact from "screens/Contact";
render(
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Homepage} />
<Route path="about" component={About} />
<Route path="contact" component={Contact} />
</Route>
</Router>,
document.getElementById("react-root")
);
Perceba que há uma instância inicial da rota e outras rotas aninhadas, formando uma hierarquia. Essa hierarquia é a essência do React Router.
Considere que temos um App (App.js
):
import React, { Component } from 'react'
import { IndexLink, Link } from 'react-router'
class App extends Component {
render() {
return (
<div>
<nav>
<IndexLink to="/">Homepage</li>
<Link to="/about">About</Link>
<Link to="/contact">Contact</Link>
</nav>
<div>
{this.props.children}
</div>
</div>
)
}
}
export default App
Dica: O componente acima não tem um estado próprio, portanto, ele é um Pure Component (ou Dumb Component). Componentes sob estas condições podem – e devem – ser transformados em Stateless Functional Components. ^[Sugiro a leitura de Functional Stateless Components in React 0.14]
Uma explicação rápida: Todas as subrotas da rota do componente App
(os <Route>
dentro de <Route>
) terão seus componentes transferidos como props para o componente App
(e por isso o this.props.children
) ao entrar na rota através do <Link>
.
A documentação do React Router dispensa quaisquer outras explicações!
3. react-helmet
Dificilmente você usará o React Router sem o Helmet. O Helmet te dá, no próprio componente, o controle do head
do documento.
Um caso de uso simples é alterar o título do documento, útil quando a aplicação entra em uma nova rota:
<Helmet title="Carrinho de Compras" />
4. jsx-control-statements
JSX facilita a escrita da marcação do componente e torna seu código mais fácil de ler e entender. Mas e quando a renderização do componente é condicional? E quando renderizamos componentes dinamicamente?
Seu código termina provavelmente assim:
<div>
{todos.map(function (todo, index) {
return <TodoItem data={todo} key={index} />;
})}
</div>
E assim:
<div>{condition && <span></span>}</div>
Ou de uma das várias outras formas: condicionais inline, operações ternárias, funções para renderizar componentes condicionalmente… Práticas que, em grande escala, podem prejudicar a legibilidade do código. E é na legibilidade que o jsx-control-statements vence.
O primeiro exemplo, por exemplo, ficaria assim:
<div>
<For each="todo" index="index" of={todos}>
<TodoItem data={todo} key={index} />
</For>
</div>
5. axios ou Fetch API
Não é uma dependência apenas de aplicações React, mas você provavelmente vai precisar de um cliente HTTP. (Um cliente HTTP de gente adulta, que não é o $.ajax
.) Existem duas ótimas opções: axios e o fetch (“WHATWG Fetch API”).
axios
Uma biblioteca maravilhosa.
A API do axios é completa: têm interceptadores de requisição, múltiplas requisições em paralelo… E suas requisições retornam lindas promises.
Fazendo uma requisição POST
:
import axios from "axios";
axios
.post(
"/api/pets",
{ name: "Bard", cat: false },
{ headers: { "X-Custom-Header": "foobar" } }
)
.then(() => console.log("Pet salvo com sucesso!"))
.catch((response) => console.log(response));
Fetch API
O fetch, por outro lado, já é um living standard, e, nesse momento, tem suporte básico nos navegadores Firefox, Chrome e Opera. É recomendado, no entanto, o uso de um polyfill, por ser uma tecnologia ainda experimental.
A mesma requisição POST
ficaria assim:
fetch("/api/pets", {
method: "post",
headers: { "X-Custom-Header": "foobar" },
body: { name: "Bard", cat: false },
})
.then(() => console.log("Pet salvo com sucesso!"))
.catch((response) => console.log(response));
Você pode saber mais sobre o Fetch API no Mozilla Developer Network.
Considerações
Embora eu tenha citado apenas cinco, existem diversas bibliotecas e componentes que descomplicam o processo de desenvolvimento de uma aplicação com React. Sem dúvidas, é um dos ecossistemas mais relevantes que front-end já teve.
Destaco que não cobri um tópico que, quando se trata de React, é bastante pertinente: formulários. Lidar com formulários no React é complicado. Nesse primeiro momento, resolvi deixar o tema de lado para não fugir da proposta do artigo.