Entrando en el mundo de Next.js Parte 2

Jonathan Rojas López
8 min readFeb 12, 2018

--

Continuando con esta inmersión que hemos hecho en el mundo de Next y teniendo ya la idea básica que nos dimos en el post anterior:

Vamos a aprender a montar un proyecto muy sencillo con Nextjs, y para empezar vamos a pensar cuáles las configuraciones y módulos que vamos a añadir. Cómo agregar estilos a nuestro proyecto de una manera más genial con emotion y a cómo organizar nuestro proyecto para que sea más agradable a la hora de ver nuestros archivos.

Los temas de esta parte serán:

  • Instalando Emotion
  • Renderizando Rutas Dinámicas.
  • Rutas Dinámicas Desde El Cliente
“Daría todo lo que sé, por la mitad de lo que ignoro” René Descartes

Instalando Emotion.js

Antes de entrar en el detalle de cómo configurar y empezar con Emotion, me gustaría contar el por qué vamos a trabajar con esta librería.

Desde hace un tiempo llevo trabajando con Css en Js y la verdad me ha gustado muchísimo esta nueva forma de estilizar los componentes y algunas de las razones por las cuales me gusta esta técnica es por que en lo personal siento que mi tiempo de desarrollo se ha reducido y que puedo tener los proyectos mejor organizados y tener más control sobre todos los estilos de los componentes, pues, si nos fijamos estamos estilizando con JavaScript y JavaScript es 😍 😻 💛💙❤️ . Que viva JavaScript!! Que viva!!

Por qué emotion ? La verdad únicamente he trabajado con Styled Components y Glamorous.js, y en lo personal me encanta glamorous.js y me he sentido demasiado cómodo trabajando con esa tecnología; de todas maneras el uso de estas tecnologías siempre es una decisión personal y es bueno que cada quien pueda leer un poco acerca de ellas y así mismo decidir qué es lo que mas le conviene, le gusta y se adapta a las necesidades. Y de donde viene el cuento mío con emotion ?, el cuento mío con emotion viene desde hace unos días en los cuales he venido leyendo acerca de ello, y viendo el progreso y las ganas que le están metiendo al proyecto. Hace pocos días ellos cambiaron la documentación y la verdad me pareció demasiado agradable lo que hicieron con su página y la documentación que allí presentan, y que también organizaron la información de emotion de una manera tan estupenda que a cualquier duda que el desarrollador tenga, podrán encontrar una respuesta muy fácil allí, y además un caso de uso en el que compararon el rendimiento de emotion con respecto a glamorous.js y styled components que fue lo que mas me llamó la atención de todo; aquí el link. Así qué, que tal si juntos aprendemos emotion ??

Primero que todo vamos a instalar todos los paquetes que necesitaremos para empezar a usar emotion

  • comando 1 => Con este comando instalamos todos los paquetes que vamos a necesitar para empezar a usar emotion.
npm install --save emotion react-emotion babel-plugin-emotion emotion-server
asi deben verse nuestras dependencias ahora

Una vez con las dependencias ya instaladas vamos a crear en la carpeta /pages un archivo llamado _document.js con el cual se podrá sobrescribir la cabecera base del documento y así mismo obtener el `critical css` de emotion. Y en este archivo añadiremos las siguientes líneas:

import Document, { Head, Main, NextScript } from 'next/document';
import { extractCritical } from 'emotion-server';
export default class MyDocument extends Document {
static getInitialProps ({ renderPage }) {
const page = renderPage();
const styles = extractCritical(page.html);
return { ...page, ...styles }
}
constructor (props) {
super(props);
const { __NEXT_DATA__, ids } = props;
if (ids) {
__NEXT_DATA__.ids = ids;
}
}
render () {
return (
<html>
<Head>
<title>With Emotion</title>
<style dangerouslySetInnerHTML={{ __html: this.props.css
}}/>
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}

Ahora vamos a comprobar que emotion este funcionando añadiendo las siguientes lines al index.js:

import React from 'react'
import styled, { hydrate } from 'react-emotion'
// Adds server generated styles to emotion cache.
// '__NEXT_DATA__.ids' is set in '_document.js'
if (typeof window !== 'undefined') {
hydrate(window.__NEXT_DATA__.ids)
}
const Title = styled('h1') (
{
color: 'blue'
},
(props) => ({
fontSize: props.fontSize
})
);
const Index = () => (
<section>
<Link href='/profile'>
<a style={linkStyle}>Profile</a>
</Link>
<Link href='/shows'>
<a style={linkStyle}>Shows</a>
</Link>
<Title fontSize='40px'>Home</Title>
<p>Hola Mundo</p>
</section>
);
export default Index;

y genial, ahora ya tenemos emotion en nuestro proyecto y podemos empezar a crear nuestros estilos de una manera más organizada y modular 🎉

Para un mayor entendimiento de los métodos hydrate y extractCritical leer aquí en la documentación de emotion

Renderizando Rutas Dinámicamente

Bien, ya hemos visto lo bonito y lo sencillo que funciona Next.js y como nos ayuda al fácil renderizado de las rutas, pero ahora, nos enfrentamos a una nueva pregunta y es cómo hacemos para renderizar rutas dinámicas. Supongamos el siguiente problema:

Ya que para este proyecto vamos a trabajar con el api de https://www.tvmaze.com/api (por motivos de simplicidad). Imaginemos que queremos renderizar cada show de tv en su propia ruta de la siguiente manera: /show/batman/ , /show/superman/ , /show/iron_man/ , /show/hulk/ , etc. Y eso nos supondría tener que crear un archivo en la carpeta pages por cada show que viene del API, ahora el problema es que, #1 no conocemos de antemano el nombre de los shows que van a venir y #2 aún si los conociéramos sería una muy mala práctica tener 10.000 archivos .js en la carpeta pages para que cada una renderice el mismo componente, solo que con diferente información. Así que vamos a la solución

Para solucionar este problema, hay que tener en cuenta que Next.js renderiza la primer vez desde el servidor, así que vamos a tener que solucionar este problema primero desde el cliente y luego desde el servidor o viceversa o mejor dicho: del mismo modo en el sentido contrario (jajaja) 😂.

Rutas Dinámicas Desde El Cliente

Lo primero que vamos a hacer es crear un archivo llamado show.js el cual va a ser el archivo que nos va a renderizar dinámicamente el show que vamos a consultar. Este archivo lo creamos en la carpeta pages con las siguientes líneas:

import {Fragment} from 'react';
import styled, { hydrate} from 'react-emotion';
import Link from 'next/link';
if (typeof window !== 'undefined') {
hydrate(window.__NEXT_DATA__.ids)
};
const Item = styled('li') ({
margin: '0 10px',
});
const show = (props) => {
const {show} = props.url.query
return (
<Fragment>
<ul>
<Item>
<Link href='/'>
<a>Home</a>
</Link>
</Item>
<Item>
<Link as='/shows/show1' href='/show?show=show1'>
<a>Show 1</a>
</Link>
</Item>
<Item>
<Link as='/shows/show2' href='/show?show=show2'>
<a>Show 2</a>
</Link>
</Item>
<Item>
<Link as='/shows/show3' href='/show?show=show3'>
<a>Show 3</a>
</Link>
</Item>
<Item>
<Link as='/shows/show4' href='/show?show=show4'>
<a>Show 4</a>
</Link>
</Item>
</ul>
<h2>Hola Desde el Show {show}</h2>
<p>Si, Funcioonaaaaaaaaaa</p>
</Fragment>
);
};
export default show;

Y vamos a dejar nuestro index.js de la siguiente manera:

import styled, { hydrate} from 'react-emotion';
import Link from 'next/link';
if (typeof window !== 'undefined') {
hydrate(window.__NEXT_DATA__.ids)
};
const Item = styled('li') ({
margin: '0 10px',
});
const Title = styled('h1') (
{
color: 'blue'
},
(props) => ({
fontSize: props.fontSize
})
);
const Index = () => (
<section>
<ul>
<Item>
<Link href='/'>
<a>Home</a>
</Link>
</Item>
<Item>
<Link as='/shows/show1' href='/show?show=show1'>
<a>Show 1</a>
</Link>
</Item>
<Item>
<Link as='/shows/show2' href='/show?show=show2'>
<a>Show 2</a>
</Link>
</Item>
<Item>
<Link as='/shows/show3' href='/show?show=show3'>
<a>Show 3</a>
</Link>
</Item>
<Item>
<Link as='/shows/show4' href='/show?show=show4'>
<a>Show 4</a>
</Link>
</Item>
</ul>
<Title fontSize='40px'>Home</Title>
<p>Hola Desde Home</p>
</section>
);
export default Index;

Para aprender un poco de lo que hemos estado haciendo aquí es lo siguiente: 1ro hemos creado multiples links y en cada uno de ellos hemos agregado el atributo href el cual nos dirige a una misma ruta que es /show y a esa ruta le estamos pasando un parámetro(query) llamado show y a ese parámetro le pasamos un valor que solo cambia de número show1, show2, show3, show4 y al hacer esto lo que sucede es que cuando hacemos click a cada uno de esos elementos nos va a redirigir a la misma ruta solo que con parámetros (query) diferentes.

Ahora lo 2do que estamos haciendo es agregar el atributo as el cual nos ayuda a renderizar esa ruta de una manera mas personalizada, lo cual significa que desde allí vamos a poder organizar nuestras rutas y hacer que se vean mucho mas agradables y legibles. Ahora si se fijan, esos valores de show1,show2... son valores que mas adelante no van a ser estáticos sino que van a ser una variable, por medio de la cual pasaremos los parámetros respectivos de cada ruta. Ahora demos un vistazo al navegador para ver si todo funciona:

si vamos al index vamos a ver esto:

vista desde el index.

y si damos click a show1:

vista desde show1

vamos a ver que nuestras rutas se muestran de una forma personalizada y organizada y ademas dinámica.

ahora demos click a show2:

vista desde show 2

Y también vamos a borrar el archivo profile.js y shows.js ya que no les necesitamos por el momento y de esta manera tendremos solo 3 archivos en la carpeta pages que son: _document.js, index.js y shows.js.

Conclusión

Hoy aprendimos como integrar emotion y como generar el critical css gracias a unos métodos ya definidos por emotion para el SSR(server side rendering) y así mismo aprendimos a crear rutas dinámicas del lado del cliente y evitarnos así la fatiga de tener que crear muchos archivos por cada ruta. Aún nos quedo faltando la parte de las rutas dinámicas del lado del servidor y podemos comprobar que falto ello, al recargar el navegador en una de las rutas de los shows, solo que eso y otras cosas mas las veremos en la siguiente parte de esta serie 👌

Por si algo aquí les dejo el link del repositorio con los cambios de hoy para que lo descarguen y jueguen con él un poco https://github.com/jonathanrojaslopez/myFirstNextApp/tree/part_2

Proximo Post En Esta Serie

…Proximamente…

--

--

Jonathan Rojas López

Software Engineer at Huge. I’m a Javascript, React, Node, and Python Lover! Also, a Father, husband, and a Proud @LDSchurch Member