我正在使用react-router-v6,我想知道是否可以记录或获取以前的URL? 我想使用基于我的浏览历史记录的条件,并检查我之前的 URL 页面是否是 x 执行某些操作,否则执行其他操作。例如:
const component = ({x: number}) => {
if (prevUrl === 'someUrl') {
x + 2;
} else {
x - 2;
}
}
或者只是简单地记录 prevUrl:
const component = ({x: number}) => {
consle.log(prevUrl)
}
如何获取 prevUrl ?
React 路由器依赖于 remix-run/history 和 History Web API。
唉,他们都不允许访问历史堆栈。 remix-run/history 允许监听位置更改,但这无法从路由器访问。
所以结论是:没有内置的方法可以知道上一页的 URL。如果您需要它,您将必须自己构建一些东西。
这是开胃菜。首先准备一个上下文来提供您的历史堆栈:
const myHistoryContext = createContext();
function MyHistoryProvider({ children }) {
const [myHistory, setMyHistory] = useState([]);
const push = (location) => setMyHistory([...myHistory, location]);
return (
<myHistoryContext.Provider value={{ myHistory, push }}>
{children}
</myHistoryContext.Provider>
);
}
const useMyHistory = () => useContext(myHistoryContext);
用于跟踪导航的容器:这将用作每个页面的嵌套路线。容器通过推送新位置来保持历史记录最新:
function Container() {
const { push } = useMyHistory();
const location = useLocation();
useEffect(() => {
push(location.pathname);
}, [location]);
return <Outlet />;
}
一些页面要与容器一起使用。首页会显示上一页的路径:
function Home() {
const { myHistory } = useMyHistory();
const previous = myHistory[myHistory.length - 2];
return <h1>Home {previous}</h1>;
}
function Contact() {
return <h1>Contact</h1>;
}
function About() {
return <h1>About</h1>;
}
应用程序中包含的所有内容:
function App() {
return (
<MyHistoryProvider>
<BrowserRouter>
<Link to="/">Home</Link>
<Link to="/contact">Contact</Link>
<Link to="/about">About</Link>
<Routes>
<Route path="/" element={<Container />}>
<Route path="/" element={<Home />} />
<Route path="/contact" element={<Contact />} />
<Route path="/about" element={<About />} />
</Route>
</Routes>
</BrowserRouter>
</MyHistoryProvider>
);
}
stackblitz 上的工作示例:https://stackblitz.com/edit/react-ts-4qykui?file=App.tsx
一些缺点:
myHistory
。如何执行此操作,请参见 https://reactrouter.com/en/6.21.2/start/concepts#locations
位置状态的一些很好的用例是:
- 告诉下一页用户来自哪里并对 UI 进行分支...
您需要使用
location.state
,您可以从useLocation
访问它。
我将展示一个完整的示例,其中包含可用于设置
state
的各种选项:
import { Link, useLocation, useNavigate } from 'react-router-dom'
function InitialPage() {
const navigate = useNavigate()
if (someCondition) {
return (
<Navigate
to="/next-page"
state={{ previousLocationPathname: location.pathname }}
/>
)
}
const onClick = () => {
navigate('/next-page', { state: { previousLocationPathname: location.pathname } })
}
return (
<div>
<Link
to="/next-page"
state={{ previousLocationPathname: location.pathname }}
>
Go To Next Page
</Link>
<Button onClick={onClick}>
Go To Next Page
</Button>
</div>
)
}
function NextPage() {
const previousLocationPathname: string | undefined =
useLocation().state.previousLocationPathname
console.log(previousLocationPathname) // Logs "/initial-page"
// Branch the UI...
}
请注意,在
InitialPage
中,我使用的是 window.location
对象;没关系。在 NextPage
上,您需要使用 location
中的 useLocation()
。