Skip to content

Commit

Permalink
correcao ortográfica
Browse files Browse the repository at this point in the history
  • Loading branch information
robertotcestari committed Feb 27, 2025
1 parent 037901d commit 2ee545d
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
---
title: Links - Repo, API, Aplicação e Figma
title: Links - Repositório, API, Aplicação e Figma
---

Como já falamos por aqui, vamos usar a aplicação final do Workshop de Next Introdutório, chamada CodanteVagas.

Para isso, você precisa baixar para sua máquina o repositório da aplicação inicial para acompanhar o Workshop.
Para isso, você precisa baixar, para sua máquina, o repositório da aplicação inicial para acompanhar o Workshop.

## Link do repositório Inicial

Você poderá baixar o repositório inicial [neste link aqui](https://github.com/codante-io/ws-next-intermediario-job-board)
Você poderá baixar o repositório inicial [neste link aqui](https://github.com/codante-io/ws-next-intermediario-job-board).

## Link da aplicação Inicial funcionando

Você poderá ver uma aplicação pronta funcionando [aqui nessa URL](https://job-board-six-gamma.vercel.app/)
Você poderá ver uma aplicação pronta funcionando [aqui nesta URL](https://job-board-six-gamma.vercel.app/).

<!-- ## Repositório final
Expand All @@ -22,4 +22,4 @@ Se você quiser consultar o repositório da aplicação pronta funcionando, [ess

Vamos utilizar uma API de vagas que foi feita pelo Codante. Para mais informações, acesse a [documentação da API](https://docs.apis.codante.io/jobs-api).

Note que, desde o último workshop também fizemos algumas atualizações na API.
Note que, desde o último workshop, também fizemos algumas atualizações na API.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
title: Apresentando o CodanteVagas
---

O CodanteVagas é um _job board_. Essa é uma aplicação em que um usuário é capaz de procurar vagas, cadastrar novas vagas e visualizar detalhes de vagas de emprego. Além de páginas estáticas `home` e `sobre`.
O CodanteVagas é um _job board_. Esta é uma aplicação em que um usuário é capaz de procurar vagas, cadastrar novas vagas e visualizar detalhes de vagas de emprego, além de páginas estáticas como `home` e `sobre`.

Construímos toda a aplicação no workshop passado. Neste workshop vamos incrementá-la com algumas funcionalidades mais avançadas.
Construímos toda a aplicação no workshop passado. Neste workshop, vamos incrementá-la com algumas funcionalidades mais avançadas.

## A aplicação inicial

Expand All @@ -22,7 +22,7 @@ Esta é a raiz da aplicação, a landing page. Note que há basicamente três se

### Sobre

Na página sobre, vamos entender na prática sobre o novo roteamento da pasta `app` do Next.js
Na página sobre, vamos entender na prática sobre o novo roteamento da pasta `app` do Next.js.

![Sobre](./About.png)

Expand All @@ -34,13 +34,13 @@ Vamos para dados dinâmicos! Entender _data fetching_ com o Next.js, exibição

### Cadastro de Vagas

Esta seção trará tudo sobre Server Actions! Vamos fazer _mutação_ de dados de acordo com as melhores práticas e de forma moderna do React e deixando mais tênue a linha divisória entre _backend_ e _frontend_.
Esta seção trará tudo sobre Server Actions! Vamos fazer _mutação_ de dados de acordo com as melhores práticas e de forma moderna do React, deixando mais tênue a linha divisória entre _backend_ e _frontend_.

![New Job](./NewJob.png)

### Detalhes de Vaga

Aqui vamos deixar nossa aplicação mais funcional - nosso usuário precisa de mais informações sobre a vaga - e é isso que iremos trazer aqui.
Aqui, vamos deixar nossa aplicação mais funcional - nosso usuário precisa de mais informações sobre a vaga - e é isso que iremos trazer aqui.

![Job](./Job.png)

Expand All @@ -54,12 +54,12 @@ Vamos criar uma página para modo de manutenção que será controlada por um mi

### Loading States e Filtros

Vamos criar telas que respondem de forma mais rápida mesmo quando os dados demoram a chegar. Também vamos implementar filtro de busca
Vamos criar telas que respondem de forma mais rápida, mesmo quando os dados demoram a chegar. Também vamos implementar um filtro de busca.

![alt text](image-1.png)

### Paginação

Também vamos implementar uma paginação
Também vamos implementar uma paginação.

![alt text](image-2.png)
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,26 @@ Middleware permite que você execute código **antes** que o request (requisiç

Apesar de ser aqui uma funcionalidade do _Next.js_, a ideia de _middleware_ não é recente. Independentemente do framework, um middleware nada mais faz do que:

1. Recebe um _request_
2. Faz (ou não) alguma coisa
3. (i) Retorna um _response_; ou (ii) passa para o próximo _middleware_
1. Recebe um _request_;
2. Faz (ou não) alguma coisa;
3. (i) Retorna um _response_; ou (ii) passa para o próximo _middleware_.

### E no Next.js?

No Next.js é a mesma coisa:

1. Middleware é uma função que recebe o request como argumento;
2. Você pode fazer algum código (adicionar _response_ _cookies_ ou _headers_)
2. Você pode fazer algum código (adicionar _response_ _cookies_ ou _headers_);
3. Independentemente do que fizer, deverá retornar
1. um `NextResponse.next()` ou `Response`; ou
2. um `NextResponse.redirect()` para redirecionar o request para outra URL; ou
3. um `NextResponse.rewrite()` para reescrever a resposta
1. um `NextResponse.next()` ou `Response`; ou
2. um `NextResponse.redirect()` para redirecionar o request para outra URL; ou
3. um `NextResponse.rewrite()` para reescrever a resposta.

### Exportando um `config`

Como a função middleware roda em _todas as rotas_, é necessário exportar um objeto de configuração chamado `config`.

O objeto _config_, por sua vez deverá ter uma propriedade chamada matcher que é um array que serve como filtro para o Middleware para rodar em apenas alguns paths específicos.
O objeto _config_, por sua vez, deverá ter uma propriedade chamada `matcher` que é um array que serve como filtro para o Middleware rodar em apenas alguns paths específicos.

#### Configuração padrão

Expand All @@ -43,15 +43,15 @@ export const config = {
};
```

Com ele o _middleware_ **não irá rodar em rotas tais como:**
Com ele, o _middleware_ **não irá rodar em rotas tais como:**

- sitemaps
- robots.txt
- favicon
- api
- arquivos estáticos
- servidor de imagem do next
- sitemaps;
- robots.txt;
- favicon;
- api;
- arquivos estáticos;
- servidor de imagem do next.

### Middleware roda no Edge!
### Middleware roda no Edge

Por mais que o Middleware rode no servidor, considere que não é possível acessar APIs do Node. Existe uma config experimental que dá suporte ao Node, mas não é garantia de que ser uma funcionalidade estável.
Por mais que o Middleware rode no servidor, considere que não é possível acessar APIs do Node. Existe uma config experimental que dá suporte ao Node, mas não é garantia de que seja uma funcionalidade estável.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Ou seja, se o fetch de dados demorar, o usuário não irá ver nada até que ele

### Qual a solução então?

A princípio não havia solução (mas agora há!). Ou você usava SSR com esses pontos negativos, ou você usava Client Side Rendering - que tem uma série de outros pontos negativos também.
A princípio, não havia solução (mas agora há!). Ou você usava SSR com esses pontos negativos, ou você usava Client Side Rendering - que tem uma série de outros pontos negativos também.

Agora, **entra o Streaming.**

Expand Down Expand Up @@ -55,7 +55,7 @@ Quando você usa o arquivo `loading`, algo como isso abaixo acontece:

```typescriptreact
<Suspense fallback={<Loading />}>
<Page />
<Page />
</Suspense>
```

Expand All @@ -77,11 +77,11 @@ Algo como:
<ComponenteEstatico />
<ComponenteEstatico2 />
<Suspense fallback={<Loading />}>
<ListaDeUsuariosComFetchDeDados />
<ListaDeUsuariosComFetchDeDados />
</Suspense>
<ComponenteEstatico3 />
```

No caso acima, O HTML dos componentes estáticos serão rapidamente servidos, já que não há fetch de dados. Enquanto a lista de usuários está carregando os dados, aparecerá uma _ui de loading_ apenas onde apareceriam os dados dinâmicos.
No caso acima, o HTML dos componentes estáticos será rapidamente servido, já que não há fetch de dados. Enquanto a lista de usuários está carregando os dados, aparecerá uma _UI de loading_ apenas onde apareceriam os dados dinâmicos.

Tudo vai ficar muito mais inteligível na prática.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
title: Streaming na Prática
---

Agora que fizemos uma breve introdução sobre Streaming, está na hora de fazermos (e observarmos) na prática o que é.
Agora que fizemos uma breve introdução sobre Streaming, está na hora de colocarmos em prática (e observarmos) o que é.

Vamos fazer uma série de exercícios mostrando como podemos fazer o loading de nossa aplicação.

### Passo 1. Deixar tudo mais lento

Ok, eu criei uma "flag" na nossa API de vagas. Se você adicionar `slow=true` como parâmetro para a rota API, tudo vai demorar bem mais para carregar.
Ok, eu criei uma "flag" na nossa API de vagas. Se você adicionar `slow=true` como parâmetro para a rota da API, tudo vai demorar bem mais para carregar.

Primeiro passo, deixe a rota de `/vagas` mais lenta usando o _query parameter_.
Primeiro passo: deixe a rota de `/vagas` mais lenta usando o _query parameter_.

#### Resolução

Expand All @@ -19,7 +19,7 @@ Para fazer isso, vamos alterar a função `fetchJobs()` para adicionar `slow=tru
```typescript {3}
async function fetchJobs() {
const res = await fetch(
' https://apis.codante.io/api/job-board/jobs?slow=true',
'https://apis.codante.io/api/job-board/jobs?slow=true',
{
cache: 'no-store',
}
Expand All @@ -34,13 +34,13 @@ async function fetchJobs() {
}
```

uma olhada na UX agora do seu código - péssima!!!!
uma olhada na UX do seu código agora - péssima!!!!

### Passo 2. Criar um `loading.tsx`

Vamos ver como podemos melhorar nossa UX apenas adicionando um arquivo - o `loading.tsx`.

Dentro do arquivo loading, vamos colocar esse código:
Dentro do arquivo loading, vamos colocar este código:

```typescript
// app/vagas/loading.tsx
Expand All @@ -49,9 +49,9 @@ export default function Loading() {
}
```

Com um arquivo e 3 linhas de código melhorou muito!
Com um arquivo e 3 linhas de código, melhorou muito!

O que acontece é que o HTML do layout + fallback é enviado para nosso navegador quase que instantaneamente. Quando os dados terminam de ser carregados no servidor, eles são adicionados e enviados ao _html_ final.
O que acontece é que o HTML do layout + fallback é enviado para o nosso navegador quase que instantaneamente. Quando os dados terminam de ser carregados no servidor, eles são adicionados e enviados ao _html_ final.

### Passo 3. Vamos deixar a rota de vaga individual lenta

Expand All @@ -69,23 +69,23 @@ async function fetchJob(jobId: string) {
}
```

Diferentemente da primeira vez, agora já temos o `loading` funcionando então a experiência não fica tão ruim assim.
Diferentemente da primeira vez, agora já temos o `loading` funcionando, então a experiência não fica tão ruim assim.

### Passo 4. Vamos adicionar comentários na vaga individual

Mas e no caso em que há múltiplos fetches de dados de diferentes fontes?
Imagine agora que nossa aplicação, ao acessar a vaga individual não apenas faz fetch dos dados daquela vaga, mas também faz fetch dos comentários associados a ela. Temos 2 endpoints agora:
Imagine agora que nossa aplicação, ao acessar a vaga individual, não apenas faz o fetch dos dados daquela vaga, mas também dos comentários associados a ela. Temos 2 endpoints agora:

1. Fetch da vaga individual
2. Fetch de comentários

Vamos adicionar a flag `slow` em ambos.

Na API deixamos o fetch da vaga individual com 2 segundos de delay, enquanto o fetch dos comentários tem 4 segundos de delay.
Na API, deixamos o fetch da vaga individual com 2 segundos de delay, enquanto o fetch dos comentários tem 4 segundos de delay.

O que vai acontecer é que **toda a página** vai demorar no mínimo 4 segundos para carregar - mesmo com o conteúdo principal já tendo sido carregado em 2 segundos!

A solução para isso é trazermos granularidade nos limites do `<Suspense>`. E é exatamente isso que iremos fazer agora.
A solução para isso é trazer granularidade nos limites do `<Suspense>`. E é exatamente isso que faremos agora.

#### Código - Carregando comentários na vaga individual

Expand Down Expand Up @@ -173,7 +173,7 @@ Tudo parece estar funcionando... mas ainda temos um problema: estamos aguardando

### Passo 5. Streaming com granularidade usando `<Suspense>`

A primeira coisa que precisamos fazer é "isolar" os componentes que consomem dados. Isso é, precisamos separar os componentes que fazem fetch de dados em componentes diferentes.
A primeira coisa que precisamos fazer é "isolar" os componentes que consomem dados. Isto é, precisamos separar os componentes que fazem fetch de dados em componentes diferentes.

Vamos criar dois componentes:

Expand All @@ -182,7 +182,7 @@ Vamos criar dois componentes:

#### Criando o componente JobDetails

Vamos criar um novo arquivo para o componente JobDetails que será responsável por buscar e exibir os detalhes da vaga:
Vamos criar um novo arquivo para o componente JobDetails, que será responsável por buscar e exibir os detalhes da vaga:

```typescript
// app/vagas/[id]/job-details.tsx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ No exercício anterior, utilizamos fallbacks simples com mensagens de `Carregand
Skeletons são versões simplificadas da UI que servem como placeholders enquanto o conteúdo real está carregando. Eles ajudam a:

- Reduzir a percepção de tempo de carregamento
- Prevenir layout shifts
- Prevenir _layout shifts_
- Dar uma ideia do conteúdo que está por vir
- Manter a consistência visual da aplicação

Expand All @@ -21,7 +21,7 @@ Vamos usar a biblioteca `react-loading-skeleton` para criar nossos skeletons. Pr
npm install react-loading-skeleton
```

Adicione os estilos necessários importando-os no seu arquivo root layout:
Adicione os estilos necessários importando-os no seu arquivo _root layout_:

```typescript
// app/layout.tsx
Expand Down Expand Up @@ -170,14 +170,14 @@ export default function Loading() {

### Dicas para criar bons Skeletons

1. Deixamos a estrutura relativamente similar: O skeleton deve refletir o layout do conteúdo real para evitar mudanças bruscas quando o conteúdo carregar.
2. É mais fácil esperar com animações: A biblioteca `react-loading-skeleton` já inclui animações por padrão.
1. **Deixamos a estrutura relativamente similar:** O skeleton deve refletir o layout do conteúdo real para evitar mudanças bruscas quando o conteúdo carregar.
2. **É mais fácil esperar com animações:** A biblioteca `react-loading-skeleton` já inclui animações por padrão.

### Resultado final

Com essas implementações, nossa aplicação agora tem:

- Loading states
- _Loading states_
- Melhor feedback visual durante o carregamento
- Transições mais suaves entre estados de loading e conteúdo
- Transições mais suaves entre estados de _loading_ e conteúdo
- Uma experiência mais profissional e polida
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ title: Estado na URL

O que é _estado na URL_ e quais as vantagens dessa abordagem?

Tradicionalmente o gerenciamento de _estado_ (_state_) em uma aplicação React é feito de duas maneiras:
Tradicionalmente, o gerenciamento de _estado_ (_state_) em uma aplicação React é feito de duas maneiras:

1. Através do hook `useState`
2. Através do `Context API`
1. Através do hook `useState`.
2. Através do `Context API`.
3. Através de bibliotecas externas de gerenciamento de _estado_ (Redux, Zustand).

Como os componentes de página (geralmente) são _Server Components_, já não é possível utilizar hooks como o `useState`.

Também o caso de uso de _estado_ global, seja através de bibliotecas externas ou Context API é cada vez menor. Isso porque foi-se percebendo que a maior parte das vezes o "_estado_" precisa ser sincronizado com o servidor. E sincronizar _estado_ global com _estado_ no servidor é uma tarefa que traz múltiplas dificuldades.
Também o caso de uso de _estado_ global, seja através de bibliotecas externas ou Context API, é cada vez menor. Isso porque foi-se percebendo que a maior parte das vezes o "_estado_" precisa ser sincronizado com o servidor. E sincronizar _estado_ global com _estado_ no servidor é uma tarefa que traz múltiplas dificuldades.

Quer um exemplo? Imagine uma busca e paginação em uma lista qualquer. Não faz sentido gerenciar estado local ou estado global já que a maioria dos casos paginação e busca ocorre no backend, e não no frontend.

Justamente esse será o exemplo que iremos utilizar: vamos fazer na prática busca e paginação utilizando a URL para guardar nosso estado e sincronizar nosso backend/API com nosso frontend.
Quer um exemplo? Imagine uma busca e paginação em uma lista qualquer. Não faz sentido gerenciar estado local ou estado global, já que na maioria dos casos paginação e busca ocorrem no backend, e não no frontend.

Justamente esse será o exemplo que iremos utilizar: vamos fazer na prática busca e paginação, utilizando a URL para guardar nosso estado e sincronizar nosso backend/API com nosso frontend.
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
title: Na prática
---

Vamos fazer, na prática, um exercício de Estado na URL.
Vamos fazer, na prática, um exercício de estado na URL.

### Modificando as chamadas da API

Eu adicionei à nossa API inicial mais dois _query parameters_ que podem ser passados pela URL da API:
Eu adicionei à nossa API inicial mais dois *query parameters* que podem ser passados pela URL da API:

1. O `page`, que será responsável pela paginação dos elementos
2. O `search`, que será responsável por uma busca textual dos elementos

:::tip
Se nada for passado para o parâmetro page, o _default_ é a primeira página (página 1).
Se nada for passado para o parâmetro `page`, o *default* é a primeira página (página 1).
:::

Agora, com esses dois parâmetros na API podemos adicionar duas novas funcionalidades: **busca textual instantânea** e **paginação**.
Agora, com esses dois parâmetros na API, podemos adicionar duas novas funcionalidades: **busca textual instantânea** e **paginação**.

As duas funcionalidades irão utilizar o estado na URL. Uma vantagem que teremos desde já é que as buscas poderão ser "compartilháveis" por URL!
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ Também queremos fazer _o caminho inverso_: quando acessarmos uma URL com um par

### Resolução - Estado na URL

Para cada tecla digitada devemos chamar nossa API. Isso significa que devemos "escutar" o evento `onChange`. Um primeiro problema está no fato de que não conseguimos utilizar um _event listener_ em server components.
Para cada tecla digitada, devemos chamar nossa API. Isso significa que devemos "escutar" o evento `onChange`. Um primeiro problema está no fato de que não conseguimos utilizar um _event listener_ em server components.

Para isso precisamos extrair nossa busca para um componente à parte e usar a diretiva `use client`.
Para isso, precisamos extrair nossa busca para um componente à parte e usar a diretiva `use client`.

Em segundo lugar, precisamos capturar o valor do input para transferir para a URL.

Expand Down Expand Up @@ -154,7 +154,7 @@ Agora é a hora de implementarmos a busca no nível da API. Quando nossa URL é

### Resolução

Em linhas simples o que precisamos fazer:
Em linhas simples, o que precisamos fazer:

1. Buscar os parâmetros da URL
2. Se houver o parâmetro `search`, devemos capturá-lo
Expand Down Expand Up @@ -245,7 +245,7 @@ Uma biblioteca famosa é o `use-debounce`. Utilize ela para facilitar a implemen

### Resolução - Debounce

Primeiro vamos instalar a biblioteca `use-debouce`. Se houver alguma dúvida, basta olhar a [documentação](https://github.com/xnimorz/use-debounce#readme).
Primeiro, vamos instalar a biblioteca `use-debounce`. Se houver alguma dúvida, basta olhar a [documentação](https://github.com/xnimorz/use-debounce#readme).

Vamos simplesmente trocar o handleChange por um `debouncedHandleChange`:

Expand Down
Loading

0 comments on commit 2ee545d

Please sign in to comment.