useContext
El hook useContext
en React se utiliza para acceder al valor de un contexto en cualquier componente funcional. Es una forma más limpia y directa de consumir contextos en comparación con el patrón tradicional de “render props” o el uso de Context.Consumer
.
¿Qué es un Contexto en React?
El Contexto permite compartir datos entre componentes sin tener que pasarlos manualmente a través de props en toda la jerarquía. Es útil para manejar estados globales o configuraciones como:
- Temas (claro/oscuro).
- Idiomas.
- Información del usuario autenticado.
Uso básico de useContext
El hook useContext
simplifica el acceso a un contexto de la siguiente manera:
const value = useContext(MyContext);
Donde:
MyContext
es el contexto creado conReact.createContext
.value
es el valor actual proporcionado por el contexto (vía unProvider
).
Ejemplo básico de useContext
- Crear un Contexto:
import React, { createContext, useContext } from "react"; const MyContext = createContext("Valor por defecto"); function App() { return ( <MyContext.Provider value="Hola desde el contexto"> <Child /> </MyContext.Provider> ); } function Child() { const value = useContext(MyContext); // Consumir el contexto return <p>{value}</p>; } export default App;
Explicación:
MyContext.Provider
envuelve los componentes que necesitan acceso al contexto.Child
usauseContext
para acceder al valor proporcionado por elProvider
.
Ejemplo con estado global
- Contexto con estado global:
import React, { createContext, useState, useContext } from "react"; const CounterContext = createContext(); function CounterProvider({ children }) { const [count, setCount] = useState(0); return ( <CounterContext.Provider value={{ count, setCount }}> {children} </CounterContext.Provider> ); } function IncrementButton() { const { count, setCount } = useContext(CounterContext); return <button onClick={() => setCount(count + 1)}>Incrementar</button>; } function DisplayCount() { const { count } = useContext(CounterContext); return <p>Contador: {count}</p>; } function App() { return ( <CounterProvider> <DisplayCount /> <IncrementButton /> </CounterProvider> ); } export default App;
Explicación:
CounterContext
almacena el estado global del contador.CounterProvider
proporciona el estadocount
y la funciónsetCount
a todos los componentes hijos.useContext
se utiliza enIncrementButton
yDisplayCount
para consumir esos valores.
Contexto anidado
Puedes tener múltiples contextos en tu aplicación. Aquí un ejemplo con tema y autenticación:
import React, { createContext, useContext, useState } from "react";
const ThemeContext = createContext();
const AuthContext = createContext();
function App() {
return (
<ThemeContext.Provider value="dark">
<AuthContext.Provider value={{ user: "John Doe" }}>
<Content />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
function Content() {
const theme = useContext(ThemeContext);
const { user } = useContext(AuthContext);
return (
<div style={{ background: theme === "dark" ? "#333" : "#fff", color: theme === "dark" ? "#fff" : "#000" }}>
<p>Hola, {user}</p>
<p>El tema actual es {theme}</p>
</div>
);
}
export default App;
Explicación:
ThemeContext
proporciona el tema (oscuro/claro).AuthContext
proporciona información del usuario autenticado.- Ambos valores se consumen con
useContext
en el componenteContent
.
Consideraciones importantes sobre useContext
- Proveer un Contexto:
- Si consumes un contexto con
useContext
pero no estás dentro de unProvider
, se usará el valor por defecto definido encreateContext
.
- Si consumes un contexto con
- Evitar el
prop drilling
:useContext
elimina la necesidad de pasar props a través de múltiples niveles de componentes.
- Re-renderizado:
- Los componentes que usan
useContext
se vuelven a renderizar automáticamente cuando cambia el valor del contexto.
- Los componentes que usan
- Ejemplo de mal uso:
- No abuses de los contextos para manejar datos que cambian frecuentemente, ya que esto puede causar re-renderizados innecesarios.
https://www.w3schools.com/react/react_usecontext.asp