Construir un buscador funcional dentro de una aplicación React implica mucho más que colocar un input en pantalla. Requiere pensar en la arquitectura del estado, decidir si la información debe vivir de forma local o global, y conectar los eventos del usuario con el flujo de datos de la aplicación. Aquí se aborda paso a paso cómo lograr un buscador por título utilizando React Context, refactorizando el estado local y capturando eventos del teclado en tiempo real.
¿Por qué mover el estado local al contexto global?
Cuando una aplicación crece, los datos que antes vivían en un solo componente empiezan a necesitarse en otros lugares. Eso es exactamente lo que ocurre con la lista de productos: inicialmente se manejaba con un estado local dentro de la página home, pero al requerirse en múltiples partes, lo más coherente es llevarlo a un estado global.
Este proceso se conoce como refactor [0:38], que consiste en reorganizar el código sin cambiar su comportamiento externo. En la práctica, el cambio implica:
- Remover el useState y el useEffect del componente home.
- Trasladar el arreglo de items y la función fetch al archivo de context [0:52].
- Proveer tanto
items como setItems desde el contexto para que cualquier componente pueda consumirlos.
Una vez hecho esto, el componente home ya no gestiona su propia data. En su lugar, importa useContext y accede a los productos directamente desde el ShoppingCartContext [1:30]. Tras guardar los cambios y verificar en el navegador, la lista de productos se muestra igual que antes, confirmando que el refactor fue exitoso [2:19].
¿Cómo agregar un input de búsqueda con estilos en Tailwind?
Con el estado global listo, el siguiente paso es crear la interfaz del buscador. Se añade un elemento <input> de tipo texto justo debajo del título de la página [3:07].
¿Qué atributos necesita el input?
El input incluye un placeholder descriptivo como "search a product" para guiar al usuario [3:23]. Para el estilo visual se utilizan clases de Tailwind CSS:
rounded-lg para bordes redondeados.
border border-black para un borde negro consistente con el diseño.
p-4 como padding interno.
w-80 o similar para definir el ancho.
mb-4 como margin bottom para separarlo de los productos [4:14].
Un detalle importante es eliminar el borde azul que aparece por defecto cuando el input recibe foco. Tailwind permite manejar pseudoclases directamente en el className usando la sintaxis focus:outline-none [4:50]. Con esto se mantiene el look and feel uniforme de toda la aplicación.
¿Cómo capturar lo que el usuario escribe en el input?
Para detectar cada tecla que el usuario presiona se utiliza el evento onChange [5:18]. Este evento recibe una función callback con el parámetro event, del cual se extrae el valor actual del campo mediante event.target.value.
Pero capturar el valor no es suficiente: hay que almacenarlo en el estado. Para ello se crea un nuevo estado en el contexto llamado searchByTitle junto con su setter setSearchByTitle [5:55]. Ambos se proveen a través del provider para que estén disponibles globalmente.
Desde el componente home, se importa setSearchByTitle del contexto y se invoca dentro del onChange del input, pasando como argumento el valor capturado [6:25].
¿Cómo verificar que la captura de datos funciona correctamente?
Para confirmar que todo el flujo opera bien, se agrega un console.log del valor de searchByTitle directamente en el contexto [6:40]. Al abrir la consola del navegador y comenzar a escribir en el input, se puede observar cómo cada carácter ingresado se refleja inmediatamente en la consola [7:01].
Este comportamiento en tiempo real es la base del filtrado dinámico: cada cambio en el input actualiza el estado global, lo que posteriormente permitirá filtrar la lista de productos y renderizar solo aquellos cuyo título coincida con el texto buscado.
El camino recorrido establece dos pilares fundamentales: un estado centralizado gracias al refactor hacia React Context y un mecanismo de captura de eventos listo para conectar con la lógica de filtrado. ¿Ya tienes ideas sobre cómo implementar el filtro comparando el texto del input con los títulos de los productos? Comparte tu enfoque en los comentarios.