Creación de Hooks Personalizados en React para Contadores Reutilizables
Clase 18 de 24 • Curso de React.js
Contenido del curso
Clase 18 de 24 • Curso de React.js
Contenido del curso
Emilio Flor
Alfonso Neil Jiménez Casallas
Alfonso Neil Jiménez Casallas
DAYAN MANRIQUE
Ramiro Cabrera
Alvaro H. Ruiz V.
Juan José Mayorquín Cabrera
Alejandro Zapata
Johan Sebastian
Yan Harold Muñoz Dominguez
Valentina Hernández
Robinson Daniel Mendoza Campo
Jose Luis Bedoya
Luis Rodolfo Altuve Cáceres
Para aquellos que todavía se lo preguntan, la diferencia entre un Hook y un Componente es crucial.
Un Hook es la lógica pura. No renderiza (dibuja) nada en la pantalla. Su única tarea es gestionar el estado y las funciones que controlan los datos, como en un carrito de compras.
Por ejemplo, en un hook llamado useCart, se manejaría toda la lógica del carrito: agregar o eliminar productos, calcular el total y persistir el estado. Es el "cerebro" detrás de la operación.
Un Componente es la interfaz visual. Si bien puede usar lógica, su función principal es renderizar la información que recibe. El componente toma los datos del hook y los muestra al usuario con estilos, botones e imágenes. Por ejemplo, el componente <Cart> mostraría la lista de productos del carrito, con botones para eliminar o ajustar la cantidad, llamando a las funciones del useCart que hacen el trabajo pesado. Es la "cara" que el usuario ve y con la que interactúa.
Seguro hay gente que lo sabe, pero esto es para el que no sabe.
hay un pequeño detalle a corregir en el custom hook "useCounter", la función "decrement" debería quedar así:
const decrement = () => setCount(prev => prev - 1) ```const decrement = () => setCount(prev => prev + 1)
por favor hacer la corrección en el repositorio curso-react/my-react-app-advanced/src/hooks/useCounter.jsx at main · platzi/curso-react
const decrement = () => setCount(prev => prev - 1)
si se hace asi el valor por defecto no seria reutilizable, como lo tiene la profesora esta bien ya que puedes darle un valor custom al momento de instanciar el hook
Un caso de uso más complejo para custom hooks en React podría ser un formulario de contacto que maneja múltiples campos y validaciones.
Aquí un ejemplo de código:
// useForm.js import { useState } from 'react'; const useForm = (initialValues, validate) => { const [values, setValues] = useState(initialValues); const [errors, setErrors] = useState({}); const handleChange = (e) => { const { name, value } = e.target; setValues({ ...values, [name]: value, }); setErrors(validate({ ...values, [name]: value })); }; const handleSubmit = (e) => { e.preventDefault(); // Lógica para enviar el formulario }; return { values, errors, handleChange, handleSubmit }; }; export default useForm; // En un componente import useForm from './useForm'; const ContactForm = () => { const validate = (values) => { const errors = {}; if (!values.email) errors.email = 'Requerido'; return errors; }; const { values, errors, handleChange, handleSubmit } = useForm({ email: '' }, validate); return ( <form onSubmit={handleSubmit}> <input type="email" name="email" value={values.email} onChange={handleChange} /> {errors.email && <p>{errors.email}</p>} <button type="submit">Enviar</button> </form> ); };
Este custom hook useForm maneja el estado del formulario y las validaciones, haciendo el componente más limpio y reutilizable.
Tome su like buen hombre. Ahora buscare implementar un debounce en el handleChange para buscar eficiencia.
También se puede reutilizar lógica de estados complejos. Por ejemplo, así quedaría el custom hook utilizando useReducer para centralizar la lógica del contador
export default function useCounter(initialValue = 0) { const [state, dispatch] = useReducer( (state, action) => { switch (action.type) { case "increment": return { count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; case "reset": return { count: initialValue }; default: return state; } }, { count: initialValue } ); const { count } = state; const increment = useCallback(() => dispatch({ type: "increment" }), [dispatch]) const decrement = useCallback(() => dispatch({ type: "decrement" }), [dispatch]) const reset = useCallback(() => dispatch({ type: "reset" }), [dispatch]) return { count, increment, decrement, reset }; }
He añadido un input para que el usuario pueda ingresar el valor inicial del contador:
import useCounter from '../../hooks/useCounter'; const CounterWithCustomHook = () => { const { count, increment, decrement, reset, set } = useCounter(0); const handleInputChange = (e) => { const numericValue = Number(e.target.value); // Convertir el valor a número set(numericValue); }; return ( <div className="card"> <h4>Counter with Custom Hook</h4> <p>Count: {count}</p> <button onClick={increment}>Increment</button> <button onClick={decrement}>Decrement</button> <button onClick={reset}>Reset</button> <input type="text" placeholder='Ingresa el valor inicial' value={count} onChange={handleInputChange} /> </div> ); } export default CounterWithCustomHook;
Ahí vamos
A custom hook in React is a JavaScript function that uses React's built-in hooks (like useState or useEffect) to encapsulate reusable logic. By creating a custom hook, you can extract common logic from components, making them cleaner and easier to maintain. For example, a custom hook for managing a counter could handle the state and provide functions to increment, decrement, and reset the counter, allowing any component to use this logic without duplicating code.
Es importante resaltar que para que un custom hook sea un custom hook, debe usar apis de react, como useContext o useState, si se usa para encapsular logica de de javascript, solo confunde!
En este caso, el ejemplo que desarrolla la profesora es correcto, ya que ciertamente usa el hook useState dentro de la definición del custom Hook, a lo que haces referencia.
Ahora, lo que si puedo aclarar es que useContext o useState forman parte de la API de React, pero no son "APIs" completas por sí mismas, sino que son funciones específicas (o Hooks) dentro de la API más amplia de React.