No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Next.js

Curso de Next.js

Jonathan Alvarez

Jonathan Alvarez

#UnderTheHood Server Side Rendering: getServerSideProps

19/27
Recursos

Aportes 19

Preguntas 6

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Desde la versión 9.4 next js tiene implementado su “versión” en el servidor, por lo que es opcional instalar otra librería
Improved Built-in Fetch Support

estuvee un raaato pero lo logré

para no tener que clavar la url en el fetch, y no tener que cambiar el codigo segun el entorno: local, stagging, produccion

podemos crear un archivo .env.local con los siguientes valores:

PROTOCOL=http(s)://
BKND_URL=localhost:3000

y luego cambiamos la funcion getServerSideProps por algo como:


export const getServerSideProps = async ()=>{
  const PROTOCOL = process.env.PROTOCOL
  const URL = process.env.BKND_URL

  const response = await fetch(`${PROTOCOL}${URL}/api/avo`)

de esta manera ya nos queda funcionando en local, y le estamos pegando a nuestra misma app local.

ahora para que funcione en produccion(vercel) debemos agregar esas variables de entorno:
para eso vamos a settings->environment variables y agregamos las 2 variables de entorno:

  • PROTOCOL de tipo Plaintext con el valor https://
  • BKND_URL de tipo Reference to System Environment Variable con el valor VERCEL_URL

estuve un rato trabado, hasta darme cuenta que la variable VERCEL_URL que proveen no tiene el protocolo.

En el min 9:14 use la de localhost y no hubo problemas

const response = await fetch('https://localhost:3000/api/avo')```

🔍 #UnderTheHood Server Side Rendering: getServerSideProps

<h4>Ideas/conceptos claves</h4>

Client Side rendered.- El Html se esta produciendo desde el cliente

<h4>Apuntes</h4>

Usamos useEffect para traer la información de la API, debido a esto estamos renderizando desde el cliente. Es decir que desde el servidor no esta información de los elementos.

Para poder extraer los datos desde el cliente lo que debemos hacer es usar la siguiente función:

export const getServerSideProps = async () => {
  // la función fetch debe de venir desde una libreria que nos ayude con la tarea
	const response = await fetch('https://platzi-avo-alpha.vercel.app/api/avo')
  const { data: productList }: TAPIAvoResponse = await response.json()
	// Devuelve un objecto el cual luego se pasara como prop
	// en el componente

  return {
    props: {
      productList,
    },
  }
}

const HomePage = ({ productList }: { productList: TProduct[] }) => {...}

🚧 importante las rutas de las peticiones no se deben hacer con una ruta relativa, debemos tener un servidor listo con una ruta absoluta.

RESUMEN: La carga desde el cliente se mueve hacia el servidor con la función getServerSideProps y retornar un objeto con una propiedad llamada prop, entonces si la API tarda en responder la pagina tardara en dar una respuesta.

getServerSideProps: aquí le decimos a next que se reciben los datos desde el servidor y no desde el cliente, con esto nos aseguramos de tener la data en nuestro html. Doc: https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering

Server side rendering mejora muchisimo el SEO de la página, pues los robots de los buscadores pueden indexar tu contenido sin ningún problema.

Puede ser un fetch o se puede hacer uan consulta directa a la base de datos

export const getServerSideProps = async () => {
  const results = await query(`
      SELECT * FROM playeras
      ORDER BY id DESC
     
  `);

  return {
    props: {
      shirts: JSON.parse(JSON.stringify(results)),
    },
  };  
};```

Si le das click muchas veces al aguacate del header lo matas y se vuelve negro!

Challenge Completed!

yes-no.tsx

import React, { useState, useEffect } from 'react'
import ButtonRef from '@components/ButtonRef'
import fetch from 'isomorphic-unfetch'
import styled from '@emotion/styled'
import { Colors, Proxy } from '@constants'
import { Button } from '@styled/Button.styled'
import Link from 'next/link'

const useContainer = (loading: boolean) => {
  return styled.div`
    padding: 25% 3rem;
    .title {
      color: ${loading ? Colors.brownDark : Colors.greenAvo};
      font-weight: bolder;
      font-size: 5rem;
      margin: 4rem 0;
    }
  `
}

export const getServerSideProps = async () => {
  const res = await fetch(`${Proxy}/api/yes-no`)
  const { yesNo: answer } = await res.json()
  return {
    props: {
      answer,
    },
  }
}

export interface QuestionYesNoProps {
  answer: boolean
}

const QuestionYesNo: React.SFC<QuestionYesNoProps> = ({ answer }) => {
  const [loading, setLoading] = useState<boolean>(true)
  const Container = useContainer(loading)

  useEffect(() => {
    if (loading) {
      setTimeout(() => setLoading(false), 500)
    }
  }, [loading])

  return (
    <Container>
      <h4>To your question the answer is....</h4>
      <h1 className="decoration-txt title">{answer ? 'YES' : 'NO'}</h1>
      <Link href={'/yes-no'}>
        <Button onClick={() => setLoading(true)}>Another Try</Button>
      </Link>
      <ButtonRef title="Go Home" href="/" />
    </Container>
  )
}

export default QuestionYesNo

api/yes-no.ts

import { NextApiRequest, NextApiResponse } from 'next'

const yesNo = (req: NextApiRequest, res: NextApiResponse) => {
  let yesNo
  const randomNumber = Math.floor(Math.random() * 10)
  if (randomNumber >= 5) {
    yesNo = true
  } else {
    yesNo = false
  }
  res.json({ yesNo })
}

export default yesNo

No entiendo, ¿de dónde viene TProduct?

en el useEffect tenia un estado que me servia para mostrar un Loading mientras se hacia la petición de datos, ahora con getServerSideProps que ocurre en el servidor como podría mostrar ese loading?

Hola Devs:
Aqui les presento mi reto, espero y les haya gustado:
Click Aqui

No tiene cursos de angular universal

Una alternativa al hardcoding para actualizar la URL de la API de la aplicación es crear un archivo index.ts en una carpeta config.

Allí colocar:

const dev = process.env.NODE_ENV !== 'production';

export const server = dev ? 'http : //localhost:3000' : 'URL Vercel de tu App'; // Cambiará dependiendo de la variable de entorno NODE_ENV

Y en tu archivo index.tsx reemplazas el string construido de fetch API, con la constante server que exportaste en el archivo index.ts de la carpeta config.

import React, { useEffect, useState } from 'react'
import { server } from '../config'; // Importas la constante server

export const getServerSideProps = async () => {

  const response = await fetch(`${server}/api/avo`); // La agregas en Fetch API

Y listo 😊, además de solucionar el error de ruta relativa, también te actualizará los cambios de la base de datos sin necesidad de volver a ejecutar un push en tu proyecto para el servidor.

Aquí mi solución al reto platzi avocados

En esta pagina, que seria un e-commerce product-listing, es recomendado utilizar static-generration (con-data) y no server side rendering. ya que la pagina seria contruida una vez and served by CDN que es mas mucho mas veloz.

Si quiero usar useEffect + SSR, cómo sería el approach? tendría que usar llamadas desde el cliente cuando me cambie el estado, pero la carga inicial va desde el server?

Mi respuesta al reto /yes-or-no