首页 > 解决方案 > 使用 React Context 现在我的导航栏不见了?

问题描述

昨天刚刚了解了反应上下文,我遇到了一些问题,道具开始在子组件中未定义。因此,我将很多被传递下来的道具制作成上下文并解决了这个问题。

也许我错了,但我的理解是,每当我在组件中创建上下文时,我需要将该组件导入我的 App.js 并将我的应用程序包装在该组件中。当我开始这样做时,我的导航栏不再渲染。它会导致我的 react-router-dom 无法正常工作。当我单击链接以路由到新组件时,它会路由..但它将组件安装在父组件内。

我究竟做错了什么?把我的头撞到这个上。

编辑:这是我完整的 App.js

FeedIndexProvider、FeedDisplayProvider 和 FeedCardProvider 只是这些组件的导入。

import React, { useState, useEffect } from "react";
import "./App.css";
import "antd/dist/antd.css";
import Auth from "./components/Auth/Auth";
import MainLayout from "./components/Site/Layout";
import FeedIndexProvider from "./components/Feed/FeedIndex";
import FeedDisplayProvider from "./components/Feed/FeedDisplay";
import FeedCardProvider from "./components/Feed/FeedCard";
export const TokenContext = React.createContext();

function App() {
  const [token, setToken] = useState("");
  const [firstName, setFirstName] = useState("");
  const [userId, setUserId] = useState();

  useEffect(() => {
    if (localStorage.getItem("token")) {
      setToken(localStorage.getItem("token"));
    }
  }, []);

  useEffect(() => {
    if (localStorage.getItem("firstName")) {
      setFirstName(localStorage.getItem("firstName"));
    }
  }, []);

  useEffect(() => {
    if (localStorage.getItem("id")) {
      setUserId(localStorage.getItem("id"));
    }
  });

  const updateToken = (newToken) => {
    localStorage.setItem("token", newToken);
    setToken(newToken);
  };

  const updatedFirstName = (newFirstName) => {
    localStorage.setItem("firstName", newFirstName);
    setFirstName(newFirstName);
    console.log(firstName);
  };

  const updatedUserId = (newId) => {
    localStorage.setItem("id", newId);
  };

  const clearToken = () => {
    localStorage.clear();
    setToken("");
  };

  const protectedViews = () => {
    return (token === localStorage.getItem("token")) |
      (localStorage.getItem("token") === !undefined) ? (
      <TokenContext.Provider value={token}>
        <FeedIndexProvider>
          <FeedDisplayProvider>
            <FeedCardProvider>
              <MainLayout clickLogout={clearToken} />
            </FeedCardProvider>
          </FeedDisplayProvider>
        </FeedIndexProvider>
      </TokenContext.Provider>
    ) : (
      <Auth
        updateToken={updateToken}
        updatedFirstName={updatedFirstName}
        updatedUserId={updatedUserId}
      />
    );
  };

  return <div className="App">{protectedViews()}</div>;
}

export default App;

这是我调用导航栏的 MainLayout:

const MainLayout = ({ clickLogout}) => {
  return (
    <Router>
      <Layout className="mainLayout">
        <Header>
          <Nav clickLogout={clickLogout} />
        </Header>
        <div className="spacer"></div>
        <Content>
          <div className="container-fluid">
            <div className="content">
              <Switch>
                <Route exact path="/">
                  <FeedIndex />
                </Route>
                <Route path="/post" component={ViewPost} />
              </Switch>
            </div>
          </div>
        </Content>
      </Layout>
    </Router>
  );
};

更新,这是我的导航

import React, { useState } from "react";
import { Link as RouterLink, BrowserRouter as Router } from "react-router-dom";
import { Anchor, Drawer, Button } from "antd";

const { Link } = Anchor;

const Nav = ({ clickLogout }) => {
  const [visible, setVisible] = useState(false);
  const showDrawer = () => {
    setVisible(true);
  };
  const onClose = () => {
    setVisible(false);
  };

  return (
    <div className="routing">
      <div className="container-fluid">
        <div className="header">
          <div className="logo">
            <img
              src="../../assets/mobile-shield.png"
              alt=""
              height="25px"
              style={{ borderRadius: "50%", marginRight: "5px" }}
            />
            <a href="https://google.com">EFA</a>
          </div>
          <div className="mobileHidden">
            <Anchor targetOffset="65">
              <RouterLink to="/">
                <a onClick={clickLogout}></a>
              </RouterLink>
            </Anchor>
          </div>
          <div className="mobileVisible">
            <Button type="primary" onClick={showDrawer}>
              <i className="fas fa-bars"></i>
            </Button>
            <Drawer
              placement="right"
              closable={false}
              onClose={onClose}
              visible={visible}
            >
              <Anchor targetOffset="65">
                <RouterLink to="/">
                  <a onClick={clickLogout}></a>
                </RouterLink>
              </Anchor>
            </Drawer>
          </div>
        </div>
      </div>
    </div>
  );
};
export default Nav;

标签: reactjs

解决方案


改变这个:

const FeedIndex = (props) => {
           ...
        
      return (
        <GetPostsContext.Provider value={getPosts}>
          <PostsContext.Provider value={posts}>
            <CreateReplyContext.Provider value={createReply}>
              <ReplyActiveContext.Provider value={replyActive}>
                <PostActiveContext.Provider value={postActive}>
                  <CreatePostContext.Provider value={createPost}>
                    <AddPostContext.Provider value={addPost}>
                      <PostOnContext.Provider value={postOn}>
                        <PostOffContext.Provider value={postOff}>
                          <AddReplyContext.Provider value={addReply}>
                            <ReplyOnContext.Provider value={replyOn}>
                              <ReplyOffContext.Provider value={replyOff}>
                                {props.children}
                              </ReplyOffContext.Provider>
                            </ReplyOnContext.Provider>
                          </AddReplyContext.Provider>
                        </PostOffContext.Provider>
                      </PostOnContext.Provider>
                    </AddPostContext.Provider>
                  </CreatePostContext.Provider>
                </PostActiveContext.Provider>
              </ReplyActiveContext.Provider>
            </CreateReplyContext.Provider>
          </PostsContext.Provider>
        </GetPostsContext.Provider>
      );
    
 }

推荐阅读