首页 > 解决方案 > 反应上下文不适用于 react-router-dom 的不同路径

问题描述

我正在使用反应上下文为我的反应站点和反应路由器存储局部变量。一切都在基本 url 上工作,但是如果我导航到其他一些 url,组件将无法使用上下文,特别是 Navbar 组件,因为我首先注意到它。任何帮助表示赞赏。

这是代码:

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./App.css";
import App from "./App";
import { AppProvider } from "./context";

ReactDOM.render(
    <React.StrictMode>
        <AppProvider>
            <App />
        </AppProvider>
    </React.StrictMode>,
    document.getElementById("root")
);

应用程序.js

import "./App.css";
import Landing from "./landing/Landing";
import PageNotFound from "./errors/pageNotFound";
import Navbar from "./Navbar";
import CreateUnoGame from "./uno/CreateUnoGame";
import UnoGame from "./uno/UnoGame";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

function App() {
    return (
        <Router>
            <Navbar></Navbar>
            <Switch>
                <Route exact path="/">
                    <Landing></Landing>
                </Route>
                <Route path="/create-uno-game">
                    <CreateUnoGame></CreateUnoGame>
                </Route>
                <Route path="/uno-game">
                    <UnoGame></UnoGame>
                </Route>
                <Route path="*">
                    <PageNotFound></PageNotFound>
                </Route>
            </Switch>
        </Router>
    );
}

export default App;

导航栏.js

import React from "react";
import "./App.css";
import { FaBars } from "react-icons/fa";
import { useGlobalContext } from "./context";

export default function Navbar() {
    const { openSubmenu, closeSubmenu, openMenu } = useGlobalContext();

    const displaySubmenu = (e) => {
        const submenuContent = e.target.textContent;
        const contentData = e.target.getBoundingClientRect();
        const horizontal = (contentData.right + contentData.left) / 2;
        const vertical = contentData.bottom;
        openSubmenu(submenuContent, { horizontal, vertical });
    };

    const hideSubmenu = (e) => {
        if (!e.target.classList.contains("link-btn")) {
            closeSubmenu();
        }
    };

    return (
        <nav className="navbar" onMouseOver={hideSubmenu}>
            <div className="nav-header">
                <a href="/">
                    <h1>Sameness</h1>
                </a>
                <ul className="nav-links">
                    <li>
                        <button
                            className="link-btn"
                            onMouseOver={displaySubmenu}
                        >
                            games
                        </button>
                    </li>
                    <li>
                        <button
                            className="link-btn"
                            onMouseOver={displaySubmenu}
                        >
                            stats
                        </button>
                    </li>
                </ul>
                <button className="btn menu-btn" onClick={openMenu}>
                    <FaBars></FaBars>
                </button>
                <button className="btn sign-in">Sign In</button>
            </div>
        </nav>
    );
}

上下文.js

import React, { useState, useContext } from "react";

const AppContext = React.createContext();

const AppProvider = ({ children }) => {
    const [isMenuOpen, setIsMenuOpen] = useState(false);
    const [isSubmenuOpen, setIsSubmenuOpen] = useState(false);
    const [submenuContent, setSubmenuContent] = useState("");
    const [location, setLocation] = useState({});
    const [unoGameId, setUnoGameId] = useState("");

    const openMenu = () => {
        setIsMenuOpen(true);
    };

    const closeMenu = () => {
        setIsMenuOpen(false);
    };

    const openSubmenu = (newSubmenuContent, positions) => {
        setIsSubmenuOpen(true);
        setSubmenuContent(newSubmenuContent);
        setLocation(positions);
    };

    const closeSubmenu = () => {
        setIsSubmenuOpen(false);
    };

    const createUnoGame = (id) => {
        console.log(id, "trying...");
        setUnoGameId(id);
    };

    return (
        <AppContext.Provider
            value={{
                isMenuOpen,
                isSubmenuOpen,
                openMenu,
                openSubmenu,
                closeMenu,
                closeSubmenu,
                setSubmenuContent,
                submenuContent,
                location,
                unoGameId,
                createUnoGame,
            }}
        >
            {children}
        </AppContext.Provider>
    );
};

export const useGlobalContext = () => {
    return useContext(AppContext);
};

export { AppContext, AppProvider };

标签: javascriptreactjsreact-router-domreact-context

解决方案


推荐阅读