我经常弹出的一个场景是数据库中的某些页面具有 Header = false 或 Page Title = false。一个很好的解决方案是上下文。
import React, { createContext, useContext, useState, useEffect } from "react";
import { Switch, Route } from "react-router-dom";
const AppContext = createContext({});
const Header = () => {
const { headerActive } = useContext(AppContext);
if (!headerActive) {
return null;
}
return (
<header>I'm a header</header>
);
}
const PageWithHeader = () => {
const { setHeaderActive } = useContext(AppContext);
useEffect(() => {
setHeaderActive(true);
},[setHeaderActive]);
return (
<div>Page with header</div>
);
}
const PageWithoutHeader = () => {
const { setHeaderActive } = useContext(AppContext);
useEffect(() => {
setHeaderActive(false);
},[setHeaderActive]);
return (
<div>Page without header</div>
);
}
export const App = () => {
const [headerActive, setHeaderActive] = useState(true);
return (
<AppContext.Provider value={{ headerActive, setHeaderActive }}>
<Header />
<Switch>
<Route path="page-1">
<PageWithHeader />
</Route>
<Route path="page-2">
<PageWithoutHeader />
</Route>
<Switch>
</AppContext.Provider>
);
}
您还可以使用自定义挂钩进一步简化它。比如:
export const useHeader = (active) => {
const { headerActive, setHeaderActive } = useContext(AppContext);
useEffect(() => {
if (active !== undefined) {
setHeaderActive(active);
}
},[setHeaderActive, active]);
return headerActive;
}
然后在原来的组件中:
const Header = () => {
const headerActive = useHeader();
if (!headerActive) {
return null;
}
return (
<header>I'm a header</header>
);
}
...
const PageWithoutHeader = () => {
useHeader(false);
return (
<div>Page without header</div>
);
}
您还可以使用 useLocation 挂钩与 useRef 配对来跟踪以前和当前的路径名,这样您就可以拥有默认状态,而无需在每个页面中声明 useHeader。