🖖 Inicio

SERVICIOS

Salir

nochedía

Ordenar listas con JavaScript, sort(), React y un custom hook

400 palabras
2 minutos
January 27, 2020
blogjavascript

Ordenar listas, fácil con sort(), que lo veamos con React, fácil con useState(), y si además queremos reutilizar la rutina para siempre, fácil con un custom hook

  1. Función sort()
  2. Con un hook

Función sort()

Para ordenar listas, nada más sencillo que utilizar la función sort(), que funciona (puedes mirarlo aquí) simplemente comparando valores:

js
const lista = [2, 5, 4, 7]
console.log(lista.sort())
// [2, 4, 5, 7]

Esto de arriba es lo mismo que hacer lo siguiente

js
const lista = [2, 5, 4, 7]
console.log(lista.sort((a, b) => a - b))
// [2, 4, 5, 7]

sort() invoca una función que recibe dos valores, y estos son los que compararemos

Si no son números y queremos un orden alfabético, haríamos lo siguiente

js
const lista = ['juan', 'palomo', 'y', 'sus cosas']
console.log(
lista.sort((a, b) => {
if (a > b) return 1
if (a < b) return -1
return 0
})
)
// ["juan", "palomo", "sus cosas", "y"]

Pero no hace falta escribir tanto, podemos expresar lo mismo con una línea

js
const lista = ['juan', 'palomo', 'y', 'sus cosas']
console.log(lista.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0)))
// ["juan", "palomo", "sus cosas", "y"]

Y si lo que tenemos son estructuras complejas, pues lo mismo

js
const lista = [
{ nombre: 'juan', edad: 50 },
{ nombre: 'alberto', edad: 40 },
{ nombre: 'aragor', edad: 2000 },
]
console.log(lista.sort((a, b) => (a.edad > b.edad ? 1 : a.edad < b.edad ? -1 : 0)))
// 0: {nombre: "alberto", edad: 40}
// 1: {nombre: "juan", edad: 50}
// 2: {nombre: "aragor", edad: 2000}

Bien

El tema es, y si esta lista la queremos mostrar en el front end?

Ningún problema, con React es tan sencillo como utilizar un estado, y en cuanto actualicemos el estado por lo que sea (un botón que se clicke, o simplemente al principio de todo) pues la lista se re-renderizará sola

Haré lo segundo, y es que se ordene al principio de todo

js
import React, { useState, useEffect } from 'react'
const Lista = () => {
const [list, setList] = useState([
{ nombre: 'juan', edad: 50 },
{ nombre: 'alberto', edad: 40 },
{ nombre: 'aragor', edad: 2000 },
])
useEffect(() => {
setList(list.sort((a, b) => (a.edad > b.edad ? 1 : a.edad < b.edad ? -1 : 0)))
}, [])
return (
<ul>
{list.map(el => (
<li>
{el.nombre}: {el.edad}
</li>
))}
</ul>
)
}
export default Lista

Y ya lo tenemos, ordenando listas utilizando el estado para trabajar con el virtual DOM sin tener (ni querer) tocar el DOM original (algo que podemos hacer, pero sin garantías de que pase lo que esperemos que pase)

El problema ahora es que esta solución es específica para nuestras necesidades

Si queremos ordenar otra lista, tendremos que repetir lo mismo pero adaptado a otras necesidades

A ver, no es un drama, tampoco es que hayamos hecho una obra de arte aquí, pero no está de más si creamos algo más abstracto y que podamos reutilizar

Lo más evidente es hacer una abstracción en forma de función

js
import React, { useState, useEffect } from 'react'
const sort_lists = ({ key, list }) =>
return list.sort((a, b) => (a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0))
const Lista = () => {
const [list, setList] = useState([
{ nombre: 'juan', edad: 50 },
{ nombre: 'alberto', edad: 40 },
{ nombre: 'aragor', edad: 2000 },
])
useEffect(() => {
setList(sort_lists('edad',list))
}, [])
return (
<ul>
{list.map(el => (
<li>
{el.nombre}: {el.edad}
</li>
))}
</ul>
)
}
export default Lista

Y ahora sí, tenemos una función para reutilizarla cuantas veces queramos

Pero y el useState? Y el useEffect?

Con un hook

Para lo anterior, y para hacerlo más bonito, podemos transformar la función en un custom hook

Y un hook no es más que una función que se ocupa de su estado, algo que aquí nosotros estamos haciendo en el componente, fuera de la función

Lo podríamos hacer así

js
import React, { useState, useEffect } from 'react'
const useSortTable = ({ listToSort, key }) => {
const [list, setList] = useState(listToSort)
useEffect(() => setList(list.sort((a, b) => (a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0))), [])
return list
}
const Lista = () => {
const list = useSortTable(
[
{ nombre: 'juan', edad: 50 },
{ nombre: 'alberto', edad: 40 },
{ nombre: 'aragor', edad: 2000 },
],
'edad'
)
return (
<ul>
{list.map(el => (
<li>
{el.nombre}: {el.edad}
</li>
))}
</ul>
)
}
export default Lista

Y si te fijas es exactamente lo mismo, pero encapsulando toda la lógica en un componente que es una función y que empieza con use (si es un hook, tiene que empezar así)

Con esto lo tenemos todo extremadamente limpio ya que el hook se encarga de

  • Establecer un estado con useState
  • Llamar a la rutina para ordenar la lista una única vez con useEffect
  • Devolver la lista ordenada, pero no como una variable sino como un estado que por lo tanto se irá actualizando si hace falta

Perfecto, y es por esto que los hooks nos gustan a todos 🤩🤩🤩

Qué tal la entrada?
👌 Bien 🙌🙌
👍 Bien, pero algunas cosas podrían explicarse mejor 😬
🤷‍♂️ Da por sentadas demasiadas cosas 😒
🤷‍♂️ A ver, hay poca chicha 😬
🤷‍♂️ Los ejemplos no son muy claros 🙇‍♂️
🤷‍♂️ No se entiende, está mal escrito 👎
✍️ Hay errores, revísalo en cuanto puedas 🙏

Newsletter de kuworking, un correo de tanto en cuanto

Quizá te interese

Privacidad
by kuworking.com
[ 2020 >> kuworking ]