React 应用程序本地存储不更新 Marvel API 应用程序中的菜单组件

问题描述 投票:0回答:2

我使用 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;
        }
    }
reactjs url-parameters
2个回答
0
投票

在您的

Menu.jsx
中,当组件正在渲染时,您只使用了一次
useEffect
,因此当您更改 localStorage 值时它不会改变。

尝试将

localStorage
添加到
useEffect
依赖项中。

useEffect(() => {
    setHeroName(localStorage.getItem('heroName'));
    setCreatorName(localStorage.getItem('creatorName'));

}, [localStorage]); // or localStorage.getItem('heroName')

0
投票

我能够通过让 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>
    )
}
© www.soinside.com 2019 - 2024. All rights reserved.