Usando Bibliotecas de Terceiros

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!

Criadores de Conteúdo

Foto do William Lima
William Lima
Fundador da Micilini

Inventor nato, escreve conteudos de programação para o portal da micilini.

Torne-se um MIC 🤖

Mais de 100 mic's já estão conectados na plataforma.