昨天刚刚了解了反应上下文,我遇到了一些问题,道具开始在子组件中未定义。我将很多被传下来的道具放到了上下文中,这解决了这个问题。
也许我错了,但我的理解是每当我在组件中创建上下文时,我都需要将该组件导入我的 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;
答案 0 :(得分:1)
改变这个:
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>
);
}