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:
MyContextes el contexto creado conReact.createContext.valuees 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.Providerenvuelve los componentes que necesitan acceso al contexto.ChildusauseContextpara 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:
CounterContextalmacena el estado global del contador.CounterProviderproporciona el estadocounty la funciónsetCounta todos los componentes hijos.useContextse utiliza enIncrementButtonyDisplayCountpara 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:
ThemeContextproporciona el tema (oscuro/claro).AuthContextproporciona información del usuario autenticado.- Ambos valores se consumen con
useContexten el componenteContent.
Consideraciones importantes sobre useContext
- Proveer un Contexto:
- Si consumes un contexto con
useContextpero no estás dentro de unProvider, se usará el valor por defecto definido encreateContext.
- Si consumes un contexto con
- Evitar el
prop drilling:useContextelimina la necesidad de pasar props a través de múltiples niveles de componentes.
- Re-renderizado:
- Los componentes que usan
useContextse 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