我使用 Marvel API 创建了一个应用程序,用于搜索角色、漫画、事件、系列和创作者并显示他们的信息。除了 Menu.jsx 组件未更新为本地存储中的值外,一切正常。例如,如果我搜索角色“Wolverine”,它会将本地存储“heroName”变量设置为“Wolverine”,但如果我再次单击徽标链接或“Heroes”链接,它不会加载这个“ heroName”进入页面。
这是 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>
);
}
这是 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>
)
}
以下是我在 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;
}
}
在您的
Menu.jsx
中,当组件正在渲染时,您只使用了一次useEffect
,因此当您更改 localStorage 值时它不会改变。
尝试将
localStorage
添加到 useEffect
依赖项中。
即
useEffect(() => {
setHeroName(localStorage.getItem('heroName'));
setCreatorName(localStorage.getItem('creatorName'));
}, [localStorage]); // or localStorage.getItem('heroName')
我能够通过让 Menu.jsx 在链接点击时重新加载来解决这个问题。这是我的新代码:
export default function Menu() {
const heroName = localStorage.getItem('heroName');
const creatorName = localStorage.getItem('creatorName');
let navigate = useNavigate();
function changeLocation(placeToGo) {
navigate(placeToGo, { replace: true });
window.location.reload();
}
return (
<Navbar expand="lg" sticky="top" className="nav-bar">
<Container>
<Navbar.Brand as={Link} to={`/${heroName}`} onClick={() => changeLocation(`/${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}`} onClick={() => changeLocation(`/${heroName}`)}>Heroes</Nav.Link>
<Nav.Link as={Link} to={"/comics"} onClick={() => changeLocation("/comics")}>Comics</Nav.Link>
<Nav.Link as={Link} to={"/events"} onClick={() => changeLocation("/events")}>Events</Nav.Link>
<Nav.Link as={Link} to={"/series"} onClick={() => changeLocation("/series")}>Series</Nav.Link>
{/* <Nav.Link as={Link} to={"/stories"}>Stories</Nav.Link> */}
<Nav.Link as={Link} to={`/creators/${creatorName}`} onClick={() => changeLocation(`/creators/${creatorName}`)}>Creators</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
)
}