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!
P粉3347213592023-09-12 14:55:56
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.