Usando Bibliotecas de Terceiros
Olá leitor, se você esteve comigo durante todo esse percurso, você chegou a utilizar algumas bibliotecas de terceiros em sua aplicação ReactJS, tais como:
Como estamos utilizando o Typescript em conjunto com o React, será que o procedimento de instalação continua sendo o mesmo? Será que não há nenhum problema em seguir aquelas lições pensando no Typescript?
Então... primeiro de tudo! Mesmo que você faça o uso dessas bibliotecas, tenha em mente que você vai precisar criar arquivos .ts
e .tsx
, em vez de .js
ou .jsx
.
Segundo, você pode seguir as lições da jornada ReactJS, mas atente-se que o Typescript é tipado, logo, algumas implementações deverão estar devidamente tipadas também.
E terceiro (e o mais importante), a instalação dessas bibliotecas costumam levar o termo @types/
antes do nome da biblioteca em sí.
Por exemplo, no TS, quando queremos instalar uma biblioteca com suporte a tipagem, fazemos isso da seguinte forma:
npm install @types/NOME-DA-BIBLIOTECA
No comando acima, nós estamos baixando a versão tipada daquela biblioteca, ou seja, sua versão com suporte ao Typescript! Fazemos isso para aproveitar o máximo do suporte com Typescript.
Apesar disso, nem sempre uma biblioteca possui suporte a tipagem, ok? Logo o uso do @types
não funciona!
Aviso Importante: Por padrão, o Typescript aceita comandos feitos em Javascript. Logo, mesmo que seus códigos em TS façam o uso de bibliotecas não tipadas, isso não importa muito, uma vez que os arquivos dessas bibliotecas estão separados em suas respectivas pastas dentro de node_modules, ou seja, no final das contas, você não receberá nenhum alerta do TS 💡
Dito isto, vamos ver na prática como cada uma daquelas bibliotecas irão se comportar em conjunto com o ReactTS 🤓
Usando o Axios com Typescript
No caso do Axios
, como estamos utilizando ele em conjunto com Typescript, nada mais justo do que fazer a instalação dele em sua versão tipada:
npm install @types/axios
Observação: Talvez o pacote @types/axios
não seja mais necessário a partir das versões mais recentes do Axios
, uma vez que os tipos já estão incluídos na biblioteca principal. Sendo assim, basta instalá-lo da forma antiga: npm install axios
.
Após a instalação do Axios
, basta que você importe a biblioteca dentro dos seus services, ou dentro de cada componente que fará o uso dele.
Vejamos um pequeno exemplo da sua utilização:
import axios from 'axios';
interface User {
id: number;
name: string;
}
const fetchUser = async (userId: number): Promise<User> => {
try {
const response = await axios.get<User>(`https://api.example.com/users/${userId}`);
return response.data;
} catch (error) {
console.error('Error fetching user', error);
throw error;
}
};
Note que passamos a interface User
dentro do comando axios.get
, isso significa que esperamos que a resposta da nossa API, tenha a mesma estrutura da nossa interface, ou seja, retorne um id
e um name
.
E se a resposta da nossa API fosse um JSON?
Simples, basta passar a interface User
como um array
, observe:
components > FetchNomes.tsx
:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
// Definindo a interface para a resposta da API
interface User {
id: number;
name: string;
}
// Função para buscar os nomes
const fetchNomes = async (): Promise<User[]> => {
try {
const response = await axios.get<User[]>('https://jsonplaceholder.typicode.com/users');
return response.data;
} catch (error) {
console.error('Erro ao buscar os nomes', error);
return [];
}
};
// Componente FetchNomes
const FetchNomes: React.FC = () => {
const [nomes, setNomes] = useState<User[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
const nomesData = await fetchNomes();
setNomes(nomesData);
} catch (error) {
setError('Não foi possível carregar os nomes.');
} finally {
setLoading(false);
}
};
fetchData();
}, []);
if (loading) {
return <div>Carregando...</div>;
}
if (error) {
return <div>{error}</div>;
}
return (
<div>
<h1>Lista de Nomes</h1>
<ul>
{nomes.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
};
export default FetchNomes;
O componente acima funciona tranquilamente, a diferença é que esperamos um array: axios.get<User[]>
.
Caso você não saiba a resposta da sua API, não há nenhum problema em tipar um Any, ok?
Vejamos agora um outro exemplo do Axios
, só que dessa vez usando o POST
:
components > EnviaDados.tsx
:
import React, { useState } from 'react';
import axios from 'axios';
// Componente EnviaDados
const EnviaDados: React.FC = () => {
const [title, setTitle] = useState<string>('');
const [body, setBody] = useState<string>('');
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
setLoading(true);
setError(null);
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
title,
body,
userId: 1 // Incluindo um campo adicional como exemplo
});
console.log('Resposta da API:', response.data);
} catch (error) {
console.error('Erro ao enviar dados', error);
setError('Não foi possível enviar os dados.');
} finally {
setLoading(false);
}
};
return (
<div>
<h1>Envie Seus Dados</h1>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="title">Título:</label>
<input
type="text"
id="title"
value={title}
onChange={(e) => setTitle(e.target.value)}
required
/>
</div>
<div>
<label htmlFor="body">Corpo:</label>
<textarea
id="body"
value={body}
onChange={(e) => setBody(e.target.value)}
required
/>
</div>
<button type="submit" disabled={loading}>
{loading ? 'Enviando...' : 'Enviar'}
</button>
</form>
{error && <div>{error}</div>}
</div>
);
};
export default EnviaDados;
Note que no comando acima, diferente do GET
, em nenhum momento foi necessário tipar a requisição POST
.
Usando o TanStackQuery com Typescript
No caso do TanStackQuery
(antiga React Query
), às versões mais novas já possuem suporte a tipagem, logo, o processo de instalação segue inalterado:
npm install @tanstack/react-query axios
A única diferença, é que você precisa se atentar na tipagem dos seus componentes quando for fazer o uso dessa biblioteca.
Visando te instruir da melhor forma, dê uma olhada no exemplo que eu preparei abaixo 🙂
1) Configuração do React Query Provider
Dentro do seu App.tsx
, você vai precisar configurar o seu provider:
import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import UserList from './UserList';
const queryClient = new QueryClient();
const App: React.FC = () => {
return (
<QueryClientProvider client={queryClient}>
<UserList />
</QueryClientProvider>
);
};
export default App;
2) Criando a função para buscar dados
Vamos criar um arquivo chamado de api.ts
, que será responsável por fazer a busca dos dados:
import axios from 'axios';
export const fetchUsers = async () => {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
return response.data;
};
3) Criando o componente para exibir os dados
Agora, crie um componente chamado de UserList.tsx
para usar o useQuery
e exibir a lista de usuários:
// UserList.tsx
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import { fetchUsers } from './api';
interface User {
id: number;
name: string;
email: string;
}
const UserList: React.FC = () => {
const { data, error, isLoading } = useQuery<User[]>({
queryKey: ['users'],
queryFn: fetchUsers,
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>An error occurred: {(error as Error).message}</div>;
return (
<ul>
{data?.map(user => (
<li key={user.id}>
<strong>{user.name}</strong> - {user.email}
</li>
))}
</ul>
);
};
export default UserList;
Vamos às explicações 😋
App.tsx
: Configura o QueryClient
e o QueryClientProvider
que fornece o contexto do TanStack Query para toda a aplicação.
api.ts
: Define a função fetchUsers
que faz uma requisição para obter a lista de usuários.
UserList.tsx
: Utiliza o useQuery
para buscar e exibir a lista de usuários. O useQuery
lida com o estado de carregamento, erro e dados.
Usando o React Router Dom com Typescript
No caso da biblioteca de rotas, você precisa instalar as duas versões da biblioteca, a versão sem tipagem e a versão com tipagem:
npm install react-router-dom
npm install @types/react-router-dom
Não é possível instalar apenas o pacote @types/react-router-dom
sem instalar a biblioteca react-router-dom
, por dois grandes motivos:
Dependências: @types/react-router-dom
é um pacote de tipos e não funciona sem a biblioteca principal. Ele fornece apenas as definições de tipo para a biblioteca existente (react-router-dom
), mas não inclui o código real da biblioteca.
Funcionalidade: Sem a instalação da biblioteca principal, você não terá os componentes e funcionalidades que react-router-dom
oferece. O pacote de tipos apenas ajuda a verificar e fornecer informações sobre o que a biblioteca faz, mas não inclui a implementação real.
Portanto, você precisa instalar as duas para obter o suporte completo 😉
Vejamos um exemplo bem simplista da utilização dessa biblioteca em conjunto com o Typescript.
1) Estrutura de Pastas
Neste exemplo, nós iremos criar a seguinte estrutura de pastas:
src/
├── components/
│ ├── Home.tsx
│ ├── Contato.tsx
│ └── Sobre.tsx
├── routes/
│ └── routes.ts
├── App.tsx
├── index.tsx
└── styles.css
2) Criando o arquivo de rotas
Crie o arquivo routes.ts
na pasta src/routes/.
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import Home from '../components/Home';
import Contato from '../components/Contato';
import Sobre from '../components/Sobre';
const AppRoutes: React.FC = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/contato" element={<Contato />} />
<Route path="/sobre" element={<Sobre />} />
</Routes>
);
};
export default AppRoutes;
3) Atualize o seu App.tsx
Atualize o arquivo da sua aplicação para que ele reconheça suas rotas:
import React from 'react';
import { BrowserRouter as Router, Link } from 'react-router-dom';
import AppRoutes from './routes/routes';
const App: React.FC = () => {
return (
<Router>
<div>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/contato">Contato</Link></li>
<li><Link to="/sobre">Sobre</Link></li>
</ul>
</nav>
<AppRoutes />
</div>
</Router>
);
};
export default App;
4) Crie seus componentes
Por fim, vamos criar nossos componentes que representam nossas páginas:
Home.tsx
:
import React from 'react';
const Home: React.FC = () => {
return <h1>Home Page</h1>;
};
export default Home;
Contato.tsx
:
import React from 'react';
const Contato: React.FC = () => {
return <h1>Contato Page</h1>;
};
export default Contato;
Sobre.tsx
:
import React from 'react';
const Sobre: React.FC = () => {
return <h1>Sobre Page</h1>;
};
export default Sobre;
Só com essas configurações, já serão mais do que o suficiente para termos suporte a biblioteca do React Router Dom no Typescript 😌
Conclusão
Nesta aula, você aprendeu a utilizar as bibliotecas de terceiros que nós vimos durante a jornada ReactJS.
Até a próxima lição!