I created an app using the Marvel API that searches characters, comics, events, series, and creators and displays their information. Everything is working properly except for the Menu.jsx component is not updating to the values that are in local storage. For example, if I search for the character "Wolverine", it sets the local storage "heroName" variable to "Wolverine," but then if I click the logo link or the "Heroes" link again, it doesn’t load this "heroName" into the page.
Here is the code in App.jsx:
export default function App() {
return (
<HashRouter>
<Menu />
<Routes>
{/* Heroes */}
<Route path={'/:hName'} element={<Home />} />
<Route exact path={'/characters/:id/comics'} element={<HeroComics />} />
<Route exact path={'/characters/:id/events'} element={<HeroEvents />} />
<Route exact path={'/characters/:id/series'} element={<HeroSeries />} />
<Route exact path={'/characters/:id/stories'} element={<HeroStories />} />
{/* Comics */}
<Route exact path={'/comics'} element={<ComicsPage />} />
{/* Events */}
<Route exact path={'/events'} element={<EventsPage />} />
{/* Series */}
<Route exact path={'/series'} element={<SeriesPage />} />
{/* Stories */}
<Route exact path={'/stories'} element={<StoriesPage />} />
{/* Creators */}
<Route path={'/creators/:cName'} element={<CreatorsPage />} />
<Route exact path={'/creators/:id/comics'} element={<CreatorComics />} />
<Route exact path={'/creators/:id/events'} element={<CreatorEvents />} />
<Route exact path={'/creators/:id/series'} element={<CreatorSeries />} />
<Route exact path={'/creators/:id/stories'} element={<CreatorStories />} />
</Routes>
<Footer />
</HashRouter>
);
}
Here is the code in Menu.jsx:
export default function Menu() {
const [heroName, setHeroName] = useState("");
const [creatorName, setCreatorName] = useState("");
useEffect(() => {
setHeroName(localStorage.getItem('heroName'));
setCreatorName(localStorage.getItem('creatorName'));
}, []);
return (
<Navbar expand="lg" sticky="top" className="nav-bar">
<Container>
<Navbar.Brand as={Link} to={`/${heroName}`} className="logo-text">Marvel App</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="ml-auto">
<Nav.Link as={Link} to={`/${heroName}`}>Heroes</Nav.Link>
<Nav.Link as={Link} to={"/comics"}>Comics</Nav.Link>
<Nav.Link as={Link} to={"/events"}>Events</Nav.Link>
<Nav.Link as={Link} to={"/series"}>Series</Nav.Link>
{/* <Nav.Link as={Link} to={"/stories"}>Stories</Nav.Link> */}
<Nav.Link as={Link} to={`/creators/${creatorName}`}>Creators</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
)
}
Here is how I’m setting and getting local storage in Home.jsx:
useEffect(() => {
localStorage.setItem('heroName', hName);
const heroName = localStorage.getItem('heroName');
setHeroName(heroName);
handleClick(heroName);
}, []);
const handleShow = async (heroID) => {
setShow(true);
try {
let data = await fetchCharactersByCharacterID(heroID);
setHero(data.data.results);
} catch (err) {
return err;
}
}
const handleClick = async (heroName) => {
try {
let data = await fetchCharacters(heroName);
setHeroes(data.data.results);
localStorage.setItem('heroName', heroName);
navigate(`/${heroName}`);
} catch (err) {
return err;
}
}
2
Answers
I was able to fix this by getting Menu.jsx to reload on link click. Here is my new code:
In your
Menu.jsx
you’re usinguseEffect
only once, when the component is rendering and therefore it’s not changing when you change the localStorage value.Try add
localStorage
to theuseEffect
dependencies.i.e.