Curso react nivel medio

Introducción
useOptimistic es un hook de React introducido para facilitar la implementación de actualizaciones optimistas. Las actualizaciones optimistas permiten reflejar cambios en la interfaz de usuario antes de que la operación asíncrona (como una solicitud de red) se complete, mejorando la experiencia del usuario al hacer que la aplicación sea más rápida y receptiva.


¿Qué es useOptimistic?

useOptimistic te permite manejar un estado local temporal que refleja los cambios deseados, incluso antes de recibir una confirmación del servidor. Si la operación falla, puedes revertir fácilmente los cambios.

Sintaxis

1const [optimisticState, updateOptimisticState] = useOptimistic(initialState, reducer);
  • initialState: El estado inicial.
  • reducer: Una función que actualiza el estado basado en las acciones realizadas.

Caso Práctico: Lista de Tareas con Actualización Optimista

Supongamos que tenemos una lista de tareas donde los usuarios pueden marcar tareas como completadas.

Código

1import React, { useOptimistic } from "react";
2
3function ListaTareas() {
4  const [tareas, setTareas] = useOptimistic(
5    [
6      { id: 1, texto: "Aprender React", completada: false },
7      { id: 2, texto: "Practicar Yoga", completada: false },
8    ],
9    (estado, accion) => {
10      switch (accion.type) {
11        case "toggle":
12          return estado.map((tarea) =>
13            tarea.id === accion.id
14              ? { ...tarea, completada: !tarea.completada }
15              : tarea
16          );
17        default:
18          return estado;
19      }
20    }
21  );
22
23  const manejarToggle = (id) => {
24    setTareas({ type: "toggle", id });
25
26    // Simulación de una solicitud al servidor
27    setTimeout(() => {
28      console.log(`Tarea ${id} actualizada en el servidor.`);
29      // Si falla, aquí puedes revertir el cambio
30    }, 1000);
31  };
32
33  return (
34    <div>
35      <h1>Lista de Tareas</h1>
36      <ul>
37        {tareas.map((tarea) => (
38          <li key={tarea.id}>
39            <label>
40              <input
41                type="checkbox"
42                checked={tarea.completada}
43                onChange={() => manejarToggle(tarea.id)}
44              />
45              {tarea.texto}
46            </label>
47          </li>
48        ))}
49      </ul>
50    </div>
51  );
52}
53
54export default ListaTareas;

Explicación

  1. Estado Optimista:
    • useOptimistic mantiene un estado que puede modificarse de forma instantánea para reflejar cambios en la UI.
  2. Reducer:
    • Define cómo se actualiza el estado basado en las acciones (en este caso, alternar tareas completadas).
  3. Simulación de Red:
    • Los cambios se aplican de inmediato en la UI, mientras se simula la solicitud al servidor.

Caso Avanzado: Crear y Revertir Cambios Optimistas

Un caso práctico sería agregar y eliminar elementos con la posibilidad de revertir cambios si la solicitud falla.

Código

1import React, { useOptimistic } from "react";
2
3function ListaDeCompras() {
4  const [articulos, setArticulos] = useOptimistic(
5    [{ id: 1, nombre: "Manzanas" }],
6    (estado, accion) => {
7      switch (accion.type) {
8        case "agregar":
9          return [...estado, { id: accion.id, nombre: accion.nombre }];
10        case "eliminar":
11          return estado.filter((articulo) => articulo.id !== accion.id);
12        default:
13          return estado;
14      }
15    }
16  );
17
18  const agregarArticulo = (nombre) => {
19    const id = Date.now(); // Generar un ID único para el optimismo
20    setArticulos({ type: "agregar", id, nombre });
21
22    // Simular una solicitud al servidor
23    setTimeout(() => {
24      const exito = Math.random() > 0.5; // Simulación aleatoria de éxito o fallo
25      if (!exito) {
26        console.error(`Error al agregar ${nombre}`);
27        setArticulos({ type: "eliminar", id }); // Revertir
28      }
29    }, 1000);
30  };
31
32  return (
33    <div>
34      <h1>Lista de Compras</h1>
35      <button onClick={() => agregarArticulo("Bananas")}>Agregar Bananas</button>
36      <ul>
37        {articulos.map((articulo) => (
38          <li key={articulo.id}>{articulo.nombre}</li>
39        ))}
40      </ul>
41    </div>
42  );
43}
44
45export default ListaDeCompras;

Explicación

  1. Agregar Optimista:
    • El artículo aparece inmediatamente en la lista después de hacer clic en el botón.
  2. Revertir Cambios:
    • Si la simulación del servidor falla, el artículo se elimina de la lista.

Diferencias Entre useOptimistic y useState

CaracterísticauseOptimisticuseState
PropósitoManejar estados optimistasManejar estados locales
Actualización DirectaSí, actualiza inmediatamente la UIRequiere lógica adicional para optimismo
Reversión de EstadoIntegrado mediante el reducerDebe implementarse manualmente

Cuándo Usar useOptimistic

  1. Mejorar la Experiencia del Usuario:

    • Ideal para interfaces donde los cambios deben reflejarse instantáneamente.
  2. Operaciones CRUD:

    • Al agregar, eliminar o modificar datos en una lista.
  3. Revertir Cambios Fácilmente:

    • Simplifica la lógica para revertir cambios en caso de fallos.

Buenas Prácticas

  1. Implementar un Reducer Claro:

    • Define cómo se actualiza el estado optimista de forma predecible.
  2. Manejar Errores:

    • Siempre implementa lógica para revertir cambios en caso de fallos en el servidor.
  3. Minimizar la Complejidad:

    • Usa useOptimistic solo cuando realmente se necesiten actualizaciones instantáneas.

Limitaciones

  1. No Sustituye el Estado Global:

    • useOptimistic está pensado para estados locales en componentes, no para sistemas de estado global como Redux.
  2. Depende del Reducer:

    • Requiere lógica explícita para manejar cada acción y actualizar el estado.

Conclusión

useOptimistic es una herramienta poderosa para manejar actualizaciones optimistas en React. Es especialmente útil en aplicaciones donde los cambios deben reflejarse instantáneamente en la UI, proporcionando una experiencia más fluida y receptiva para el usuario.