_app.js 里面的代码如下
function MyApp({Component, pageProps}) {
const [user, setUser] = useLocalStorage()
const value = useMemo(() => ({user, setUser}), [user, setUser]);
return <SSRProvider>
<UserContext.Provider value={value}>
<Layout>
<Component {...pageProps} />
<ToastContainer position={'top-center'} theme={'dark'}/>
</Layout>
</UserContext.Provider>
</SSRProvider>
}
useLocalStorage 代码如下
// Hook
import {useState} from "react";
export const useLocalStorage = (key, initialValue) => {
// State to store our value
// Pass initial state function to useState so logic is only executed once
const [storedValue, setStoredValue] = useState(() => {
try {
// Get from local storage by key
const item = window.localStorage.getItem(key);
// Parse stored json or if none return initialValue
return item ? JSON.parse(item) : initialValue;
} catch (error) {
// If error also return initialValue
// console.log(error);
return initialValue;
}
});
// Return a wrapped version of useState's setter function that ...
// ... persists the new value to localStorage.
const setValue = (value) => {
try {
// Allow value to be a function so we have same API as useState
const valueToStore = value instanceof Function ? value(storedValue) : value;
// Save state
setStoredValue(valueToStore);
// Save to local storage
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
// A more advanced implementation would handle the error case
// console.log(error);
}
};
return [storedValue, setValue];
}
export const getCookie = (name,cookie) => {
const value = `; ${cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
Layout.js 代码如下
import Meta from "./Meta";
import {Container, Nav, Navbar, NavDropdown} from "react-bootstrap";
import {useContext} from "react";
import {UserContext} from "../utils/userContenxt";
import jsCookie from "js-cookie";
import Router from "next/router";
export const Layout = ({children}) => {
const {user} = useContext(UserContext)
if (user === undefined) return (<>
<Meta/>
<Container>{children}</Container>
</>)
const {menu} = user
function handleLogout() {
localStorage.removeItem('u')
jsCookie.set('token', '')
Router.push('/login')
}
return (<>
<Meta/>
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Container>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav"/>
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="me-auto">
{menu.map(item => (<NavDropdown key={item.id} title={item.name} id="collasible-nav-dropdown">
{item.Children.map(item => (item.divide === 1 ? <NavDropdown.Divider/> : <NavDropdown.Item onClick={() => Router.push(item.path)}>{item.name}</NavDropdown.Item>))}
</NavDropdown>))}
</Nav>
<Nav>
<Nav.Link eventKey={2} href="#memes">
{user.u.uname}
</Nav.Link>
<Nav.Link onClick={() => handleLogout()}>退出</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
{children}
</>)
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.