Manejando el Modo Oscuro y la Barra Lateral con Contexto en React.
toscadev
@ ToscaDevsJS
En este artículo, vamos a explorar cómo crear un contexto de aplicación en React que nos permita manejar el modo oscuro y una barra lateral desplegable.
El Contexto proporciona una forma de pasar datos a través del árbol de componentes sin tener que pasar props manualmente en cada nivel.
En otras palabras, el Contexto en React es como un almacenamiento global para nuestros datos de aplicación.
Instalando dependencias
npm i js-cookie
npm i --save-dev @types/js-cookie
CÓDIGO COMPLETO
Añadimos una carperta Context/AppContext.tsx: Donde vamos a crear nuestro contexto.
"use client";
import React, { createContext, useState, useContext, useEffect } from "react";
import Cookies from "js-cookie";
interface IAppContext {
isDarkMode: boolean;
toggleDarkMode: () => void;
isSidebarOpen: boolean;
toggleSidebar: () => void;
}
// Crear el Context
export const AppContext = createContext<IAppContext | undefined>(undefined);
// Crear el Provider
export const AppProvider = ({ children }: { children: React.ReactNode }) => {
// Añadiendo los hooks
const { isSidebarOpen, toggleSidebar } = useToggleSidebar();
const { isDarkMode, toggleDarkMode } = useToggleDarkModeJSCokiee();
return (
<AppContext.Provider
value={{ isDarkMode, toggleDarkMode, isSidebarOpen, toggleSidebar }}
>
{children}
</AppContext.Provider>
);
};
// Hook para acceder al contexto más validar que exista el contexto
export const useAppContext = () => {
const context = useContext(AppContext);
if (!context) {
throw new Error(
"No hay proveedor de autenticación, el <userProvider> no está envolviendo el componente."
);
}
return context;
};
//Hooks de toggle para el modo oscuro y el menú lateral
const useToggleSidebar = () => {
const [isSidebarOpen, setIsSidebarOpen] = useState<boolean>(false);
// Función para abrir/cerrar el menú lateral
const toggleSidebar = () => setIsSidebarOpen(!isSidebarOpen);
return { isSidebarOpen, toggleSidebar };
};
const useToggleDarkMode = () => {
const [isDarkMode, setIsDarkMode] = useState<boolean>(false);
// Función para cambiar el modo oscuro
const toggleDarkMode = () => setIsDarkMode(!isDarkMode);
return { isDarkMode, toggleDarkMode };
};
const useToggleDarkModeLocalStorrage = () => {
const [isDarkMode, setIsDarkMode] = useState<boolean>(false);
// Leer el estado del modo oscuro del localStorage al cargar la página
useEffect(() => {
const darkModeStorage = localStorage.getItem("darkMode");
if (darkModeStorage !== null) setIsDarkMode(darkModeStorage === "true");
}, []);
// Función para cambiar el modo oscuro
const toggleDarkMode = () => {
const newIsDarkMode = !isDarkMode;
setIsDarkMode(newIsDarkMode);
// Guardar el estado del modo oscuro en el localStorage
localStorage.setItem("darkMode", String(newIsDarkMode));
};
return { isDarkMode, toggleDarkMode };
};
const useToggleDarkModeJSCokiee = () => {
const [isDarkMode, setIsDarkMode] = useState<boolean>(false);
// Leer el estado del modo oscuro del localStorage al cargar la página
useEffect(() => {
const darkModeCookie = Cookies.get("darkMode");
if (darkModeCookie !== undefined) setIsDarkMode(darkModeCookie === "true");
}, []);
// Función para cambiar el modo oscuro
const toggleDarkMode = () => {
const newIsDarkMode = !isDarkMode;
setIsDarkMode(newIsDarkMode);
Cookies.set("darkMode", String(newIsDarkMode), { expires: 5 });
};
return { isDarkMode, toggleDarkMode };
};
envolvemos nuestro componente principal con el provider para poder comsumir el contexto en toda la aplicación.
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="es">
<body className={inter.className}>
<AppProvider>{children}</AppProvider>
</body>
</html>
);
}
Consumiendo el contexto en un componente ToogleDarkMode.tsx
"use client";
import { useEffect } from "react";
import { useAppContext } from "@/context/AppContext";
export const ToogleDarkMode()=> {
const { isDarkMode, toggleDarkMode, isSidebarOpen, toggleSidebar } = useAppContext();
useEffect(() => {
document.body.classList.toggle("bg-gray-900", isDarkMode);
}, [isDarkMode]);
return (
<>
<button onClick={toggleDarkMode}>Cambiar Modo {isDarkMode ? "🌙" : " ☀️"}</button>
</>
);
}
NOTAS DEL DESARROLLADOR
Los hooks de toggle para el modo oscuro y el menú lateral si su código empieza a crecer deberian ser exportados a la carpeta de los hooks.
Si te gusto esta guía no dudes en compartirla o sugerir tu opinión. ❤️