cover
Adelly Lima

Adelly Lima

30 Mai 2024 8 min read

Explorando Next.js: Manipulação de Dados

Na Labcodes, tive a oportunidade de trabalhar ativamente em um projeto Next.js, onde pude explorar várias funcionalidades da tecnologia para manipulação de dados. O Next.js oferece uma ampla variedade de recursos que tornam o desenvolvimento web mais eficiente e facilitam a manutenção do código. Usando o exemplo de um blog, vamos analisar diferentes métodos de carregamento de dados, como carregamento estático, rendering do lado do servidor e rendering do lado do cliente.

A partir da versão 13 do Next.js, houve uma mudança significativa com a introdução do app router, que altera a forma como aplicativos Next.js são estruturados. O app router oferece um novo paradigma, embora o pages router ainda seja compatível e bastante utilizado. Essa mudança pode influenciar a forma como você trabalha com técnicas como Static Site Generation (SSG), Server-side Rendering (SSR) e Client-side Rendering (CSR), então é importante estar atento a essa atualização.

Mas antes de mergulhar nas funções específicas, é importante entender como o Next.js lida com o fluxo de dados. Next.js é uma ferramenta que permite criar aplicativos web modernos, oferecendo funcionalidades como pré-renderização e roteamento automático. Essas características ajudam a otimizar o desempenho e melhorar a experiência do usuário ao lidar com dados.

Pré-renderização de páginas estáticas: getStaticProps

No Next.js, o getStaticProps é uma função fundamental para carregar dados de forma estática nas suas páginas. Mas o que isso realmente significa?

É uma função que permite pré-renderizar páginas estáticas durante a compilação da sua aplicação Next.js. O que eu quero dizer é que ele permite que você carregue dados de forma estática antes mesmo da página ser carregada pelo usuário.

Imagine que você tem um site com conteúdo que raramente muda, como uma página de blog. Em vez de carregar esses dados a cada vez que alguém acessa a página, você pode usar o getStaticProps para gerar essas páginas de forma estática durante a construção da aplicação. Isso garante que as páginas carreguem mais rapidamente e proporcionem uma experiência de usuário mais fluida.

Vamos considerar o seguinte cenário com o exemplo simples de como usar o getStaticProps em uma página do Next.js:

import React from 'react';

function Posts({ posts }) {
  return (
    <div>
      <h1>Blog</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.nome}</li>
        ))}
      </ul>
    </div>
  );
}

export async function getStaticProps() {

  const response = await fetch('https://api.exemple.com/posts');
  const data = await response.json();

  return {
    props: {
      posts: data,
    },
  };
}

export default Posts;

Nesse exemplo, a função getStaticProps é usada para buscar dados de uma API externa (fictícia) e passá-los para a página de Posts como uma propriedade. Esses dados são pré-renderizados durante a construção da aplicação e enviados para o client quando ele acessa a página. Então, em resumo, ele permite você pré-renderizar páginas estáticas com dados dinâmicos, dando uma experiência mais rápida para o usuário.

Gerando páginas dinâmicas: getStaticPaths

A getStaticPaths é uma função que permite gerar páginas dinâmicas com caminhos estáticos durante o processo de compilação. Isso é especialmente útil quando você precisa criar páginas dinâmicas com base em dados variáveis, como IDs de produtos ou categorias em um site de comércio eletrônico.

Vamos continuar usando uma aplicação de um Blog como exemplo para explicar como o getStaticPaths funciona: Suponha que você esteja construindo um blog e deseja criar páginas dinâmicas para cada post. Aqui está como você pode usar o getStaticPaths para isso em 3 passos:

1. Definindo rotas dinâmicas:

Primeiro, você define suas rotas dinâmicas em um componente de página usando colchetes [] para indicar que essas rotas são dinâmicas. Por exemplo, você pode ter uma rota como /blog/posts/[id], onde id é o identificador único de cada post.

2. Implementando o getStaticPaths:

Então, você implementa a função getStaticPaths em sua página [id].js. Esta função será responsável por retornar uma lista de todos os possíveis valores de id que suas páginas podem ser geradas.

export async function getStaticPaths() {
  const ids = await fetchPostsIds();

  const paths = ids.map((id) => ({
    params: { id: id },
  }));

  return {
    paths: paths,
    fallback: false
  };
}

A fetchPostsIds é uma função fictícia que busca os ids dos seus posts.

3. Renderizando a página dinâmica:

Agora, vamos usar os dados obtidos pela função getStaticPaths para gerar as páginas correspondentes durante o processo de build. Assim, quando um usuário acessa essas páginas, o Next.js entrega o HTML pré-gerado, garantindo tempos de carregamento mais rápidos.

export async function getStaticProps({ params }) {
  const postData = await fetchPostData(params.id); 
  return {
    props: {
      postData,
    },
  };
}

export default function Post({ postData }) {
  return (
    <div>
      <h1>{postData.title}</h1>
      <p>{postData.content}</p>
    </div>
  );
}

O getStaticPaths irá definir as rotas dinâmicas e gerar as páginas para cada post. A função fetchPostData é fictícia e deve buscar os IDs dos posts na API. Em seguida, mapeamos esses IDs para criar um array de objetos params, onde cada objeto tem a estrutura { params: { id: 'id_do_post' } }.

Já o getStaticProps usamos para buscar os dados do post com base no ID fornecido pela rota dinâmica. A função fetchPostData é fictícia e deve buscar os dados do post na API com base no ID fornecido.

Esse é um exemplo básico de como usar getStaticPaths no Next.js para criar páginas dinâmicas para posts de um blog.

Carregamento de dados no servidor para páginas: getServerSideProps

O getServerSideProps é uma função que permite carregar dados de forma dinâmica durante a renderização da página no servidor. Isso significa que os dados são buscados toda vez que a página é solicitada, ou seja, os dados estarão sempre atualizados.

Usando o Blog como exemplo vamos ver como usar o getServerSideProps: Vamos supor que você que você tenha um blog com várias postagens e uma página para exibir os detalhes de cada postagem. Você precisa buscar essas informações em um banco de dados ou em uma API sempre que alguém acessar a página de detalhes de uma postagem. É aí que temos o getServerSideProps.

Veja como você pode usar o getServerSideProps em uma página no Next.js para exibir os detalhes de uma postagem do Blog:

import axios from 'axios';

function PostPage({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      <p>Autor: {post.author}</p>
    </div>
  );
}

export async function getServerSideProps(context) {
  const postId = context.params.postId;
  const response = await axios.get(`https://api.exemple.com/posts/${postId}`);
  const post = response.data;

  return {
    props: {
      post,
    },
  };
}

export default PostPage;

Nesse exemplo, a função getServerSideProps recebe um objeto context como argumento, que contém informações sobre a solicitação atual, como parâmetros da URL. Usamos essas informações para buscar os dados da postagem na API.

Quando a página é carregada, o Next.js chama automaticamente a função getServerSideProps no servidor, obtém os dados da postagem e os passa para a página PostPage como props. Isso fará com que os dados estejam sempre atualizados e acessíveis durante a renderização da página.

Uma dica ao usar o getServerSideProps é garantir que você esteja recebendo apenas os dados necessários para a página em questão. Evite buscar grandes volumes de dados ou realizar operações complexas dentro dessa função, pois isso pode tornar o carregamento da página lento.

É importante lembrar de lidar com possíveis erros que possam acontecer durante a busca dos dados. Um exemplo comum é try/catch para tratar os erros e dar esse feedback para o usuário.

Busca de dados interativa: Client-side Fetching

Client-side Fetching acontece quando o navegador do usuário solicita informações de um servidor e as exibe sem recarregar a página inteira. Imagine carregar seu perfil ao fazer login ou ver as últimas postagens em redes sociais sem precisar atualizar a página, é isso que a busca de dados no lado do cliente permite.

Essa técnica é muito comum e essencial para que o usuário tenha os dados atualizados sempre que houver uma mudança/interação. Em vez de esperar a página recarregar, os dados são carregados em segundo plano, o que faz com que o aplicativo pareça mais rápido e interativo. Isso é feito enviando uma solicitação do navegador (por exemplo um GET) para o servidor, que vai realizar essa busca e envia de volta os dados solicitados.

Usando o mesmo exemplo de um Blog vamos ver de uma forma simples como funciona o Fetching no Client-side:

import { useState, useEffect } from 'react';
import axios from 'axios';

function PostsPage() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const response = await axios.get('https://api.exemple.com/posts');
        setPosts(response.data);
      } catch (error) {
        console.error('Error when searching for posts:', error);
      }
    };

    fetchPosts();
  }, [posts]); 
  return (
    <div>
      <h1>Latest Posts</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default PostsPage;

Nesse exemplo, usamos o hook useEffect (que pode ser perigoso caso suas dependências não sejam bem especificadas causando o mais temido looping) para buscar os posts assim que o componente PostsPage é montado. Ao acessar a página, os dados são buscados de forma assíncrona da API fictícia e armazenados no estado local da aplicação utilizando o useState. Em seguida, os posts são renderizados na página conforme são recebidos.

Uma vantagem do Client-side Fetching é a capacidade de buscar e exibir dados sem interromper a experiência do usuário. Isso significa que as páginas podem carregar rapidamente e os usuários podem interagir com o conteúdo enquanto os dados são buscados em segundo plano.

O uso de client-side fetching pode levar a solicitações excessivas, especialmente em páginas com muitos componentes que buscam dados independentemente. Para otimizar isso e garantir uma experiência mais suave para o usuário, é recomendável usar bibliotecas como react-query, swr ou RTK em projetos Next.js.

Conclusão

Para concluir, as diferentes técnicas do Next.js, como Static Site Generation (SSG), Server-side Rendering (SSR) e Client-side Rendering (CSR), ajudam a lidar com dados de forma eficiente, melhorando o desempenho e a experiência do usuário.

A getStaticProps e a getStaticPaths fazem parte da técnica de Static Site Generation (SSG), que pré-renderiza páginas estáticas durante a compilação do projeto. Isso permite que as páginas sejam carregadas rapidamente e são ideais para conteúdos que não mudam com frequência.

Por outro lado, a função getServerSideProps está relacionada ao Server-side Rendering (SSR), que carrega dados no servidor toda vez que a página é acessada. Isso garante que os dados estejam sempre atualizados quando o usuário visita a página, proporcionando uma experiência mais consistente. Por fim, o Client-side Rendering (CSR) é implementado com hooks como useEffect e bibliotecas de gerenciamento de estado para buscar dados no cliente. Isso proporciona uma experiência mais dinâmica e interativa, embora a velocidade de carregamento possa variar conforme a base de dados utilizada.

Cada uma dessas técnicas tem seus benefícios e casos de uso específicos, e a escolha da melhor opção depende das necessidades particulares do projeto. Obrigada pela leitura e até a próxima!

Referências

Next.js data fetching

Udemy - React complete guide

Next.js tutorial