I'm trying to use state management to modify my application and make it more versatile. Basically my app is a React web app with a tableau dashboard embedded and I need to populate a specific route (containing a specific dashboard) in the app by reading a json from the backend specifying the items we want .
I need it in two ways:
UI project switching allows me to switch between projects JWT received from login attempt via frontend (after success) I think the only state that needs to be managed is the navigation bar and its data, which will render the relevant paths and thereby enable relevant dashboards only by project/user.
This is the code for my navigation bar:
import React, { useState, useEffect } from "react";
import { Link, useLocation } from "react-router-dom";
import { NavbarData } from "./NavbarData";
import { IconContext } from "react-icons";
import "./Navbar.css";
import Hamburger from "./Icons/Hamburger.svg";
import "./Icons/p_logo_color.png";
import Persona from "./Icons/Persona.svg";
import Logout from "./Icons/Logout.svg";
//someting
//Navbar function
function Navbar() {
const [sidebar, setSidebar] = useState(false);
const showSidebar = () => setSidebar(!sidebar);
const [pageName, setPageName] = useState('Operational Overview');
const location = useLocation();
const getPageTitleByUrl = (path) => {
NavbarData.filter((navItem) => {
if(navItem.path === path) {
setPageName(navItem.title);
}
return true;
} )
};
const userConfigPageTitle = (path) => {
setPageName("User Information");
}
useEffect(() => {
if(location.pathname) {
getPageTitleByUrl(location.pathname);
}
}, [location] );
return (
<>
<IconContext.Provider value={{ color: "undefined" }}>
<div className="navbar">
<Link to="#" className="menu-bars">
<img src={Hamburger} alt="hamburger" onClick={showSidebar} />
</Link>
<div className="criminal-records">Elecciones Guatemala |</div>
<div className="pageTitle"><h1>{pageName}</h1></div>
<>
<div><img className="userIcon" src={Persona} alt="persona" /> </div>
<div className="userButton">User123#</div>
</>
<Link to='/' className="logout-button">
<div><img className="logoutIcon" src={Logout} alt="persona" /> </div>
<div className="logoutButton">Logout</div>
</Link>
</div>
<nav className={sidebar ? "nav-menu active" : "nav-menu"}>
<ul className="nav-menu-items" onClick={showSidebar}>
<li className="navbar-toggle">
</li>
{NavbarData.map((item, index) => {
return (
<li key={index} className={item.cName}>
<Link to={item.path}>
<span className="navbutton-icon">{item.icon}</span><span className="navbutton-text" >{item.title}</span>
</Link>
</li>
);
})}
</ul>
</nav>
</IconContext.Provider>
</>
);
}
export default Navbar;
This is NavbarData:
import React from 'react'
import startpageIcon from './Icons/startpage.svg';
import performance from './Icons/performance.svg';
import bars from './Icons/bars.svg';
import simulation from './Icons/simulation.svg';
import fraud from './Icons/fraud.svg';
import deployForNow from './Icons/Profiles.svg';
import Planning from './Icons/plan.svg';
import deployment from './Icons/layer1.svg';
import barswithperson from './Icons/barswithperson.svg'
export const NavbarData = [
{
title: 'Simulación',
path: '/monitoringoverview',
icon: <img src={simulation} alt="" />,
cName: 'nav-text'
},
{
title: "Empadronados",
path: "/performancequality",
icon: <img src={barswithperson} alt="" />,
cName: 'nav-text'
}
]
So basically what I need is to connect the dropdown switcher to change the json structured data inside the NavbarData and define each of these changes as a state. So, since this is a very simple state management task, I want to solve it using React Context, how do I do that?
Thanks in advance!
Use React Context to control the status of the navigation bar:
§ To define the context and its initial state, create a file called NavbarContext.js.
import React, { createContext, useState } from "react"; export const NavbarContext = createContext(); export const NavbarProvider = ({ children }) => { const [navbarData, setNavbarData] = useState([]); return ( <NavbarContext.Provider value={{ navbarData, setNavbarData }}> {children} </NavbarContext.Provider> ); };§ Use the NavbarProvider component to surround your application or a target area within your application, this should be done in your main file (i.e. App.js).
import { NavbarProvider } from "./NavbarContext"; function App() { return ( <NavbarProvider> {/* Your app components */} </NavbarProvider> ); } export default App;§ Using context to manipulate state, you can modify the navigation bar component accordingly.
import React, { useContext, useEffect } from "react"; import { Link, useLocation } from "react-router-dom"; import { IconContext } from "react-icons"; import { NavbarContext } from "./NavbarContext"; import "./Navbar.css"; function Navbar() { const { navbarData, setNavbarData } = useContext(NavbarContext); const [sidebar, setSidebar] = useState(false); const showSidebar = () => setSidebar(!sidebar); const [pageName, setPageName] = useState("Operational Overview"); const location = useLocation(); const getPageTitleByUrl = (path) => { navbarData.forEach((navItem) => { if (navItem.path === path) { setPageName(navItem.title); } }); }; useEffect(() => { if (location.pathname) { getPageTitleByUrl(location.pathname); } }, [location, navbarData]); return ( <> <IconContext.Provider value={{ color: "undefined" }}> {/* Rest of your code */} </IconContext.Provider> </> ); } export default Navbar;§ When receiving JSON data for the navbar (usually after logging in), you can update the navbarData state using the setNavbarData function in the context.
import { useContext, useEffect } from "react"; import { NavbarContext } from "./NavbarContext"; function YourComponent() { const { setNavbarData } = useContext(NavbarContext); useEffect(() => { // Fetch your JSON data from the backend const fetchData = async () => { try { const response = await fetch("/api/navbarData"); const data = await response.json(); setNavbarData(data); // Update the navbarData state with the fetched data } catch (error) { console.log("Error fetching data:", error); } }; fetchData(); }, [setNavbarData]); return <div>Your component content</div>; } export default YourComponent;Updating the navbarData state using setNavbarData now causes the navbar component to re-render, ultimately causing the updated data to be displayed in the navbar.
React Router requires the correct setup, and the correct dependencies must be imported into your code. Make a note to verify that these steps have been completed.