And*_*ndy 4 single-page-application typescript reactjs react-router
我正在 React 中的 SPA 中工作,不使用 React Router 来创建任何路由;我不需要允许用户导航到特定页面。(想想多页调查问卷,按顺序填写。)
但是,当用户按下浏览器上的后退按钮时,我不希望他们退出整个应用程序;我希望能够在用户按下后退按钮时触发一个功能,该功能只需将页面呈现为上次选择之前的样子。(每个页面都是一个组件,它们组装在一个数组中,由currentPage状态变量(来自状态挂钩)跟踪,因此我可以简单地渲染pages[currentPage -1].
使用(如果需要)当前版本的 React Router (v5)、函数组件和 Typescript,我如何访问后退按钮事件以禁用它并用我自己的函数替换它?
(我发现的其他答案要么使用类组件、特定于旧版本 React Router 的函数,要么使用特定框架,例如 Next.js。)
任何和所有的见解都会受到赞赏。
经过太多时间的工作,我找到了解决方案。因为一旦我找到正确的路径,最终并不那么困难,我发布我的解决方案,希望它可以节省其他人的时间。
npm install --save react-router-dom @types/react-router-dom。{ BrowserRouter, Route, RouteComponentProps, withRouter }于react-router-dom。history通过解构传入RouteComponentProps:
function MyComponent( { history }: ReactComponentProps) {
...
}
Run Code Online (Sandbox Code Playgroud)在屏幕状态更改(用户将其视为新页面)上添加一个空白条目history;例如:
function MyComponent( { history }: ReactComponentProps) {
const handleClick() {
history.push('')
}
}
Run Code Online (Sandbox Code Playgroud)
这会在历史记录中创建一个空白条目,因此历史记录具有后退按钮可以访问的条目;但用户看到的 url 不会改变。
componentDidMount)在函数组件中不起作用。请确保useEffect从 导入react。)
useEffect(() => {
// code here would fire when the page loads, equivalent to `componentDidMount`.
return () => {
// code after the return is equivalent to `componentWillUnmount`
if (history.action === "POP") {
// handle any state changes necessary to set the screen display back one page.
}
}
})
Run Code Online (Sandbox Code Playgroud)withRouter并创建一个可以访问路由属性的新组件:
const ComponentWithHistory = withRouter(MyComponent);
Run Code Online (Sandbox Code Playgroud)现在将其全部包装在 a<BrowserRouter />和 a<Route />中,以便 React Router 将其识别为路由器,并将所有路径路由到path="/",这将捕获所有路由,除非指定了具有更具体路径的路由(无论如何,使用此设置,它们都是相同的,由于history.push("");历史看起来像["", "", "", "", ""])。
function App() {
return (
<BrowserRouter>
<Route path="/">
<ThemeProvider theme={theme}>
<ComponentWithHistory />
</ThemeProvider>
</Route>
</BrowserRouter>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)完整的示例现在看起来像这样:
function MyComponent( { history }: ReactComponentProps) {
// use a state hook to manage a "page" state variable
const [page, setPage] = React.useState(0)
const handleClick() {
setPage(page + 1);
history.push('');
}
useEffect(() => {
return () => {
if (history.action === "POP") {
// set state back one to render previous "page" (state)
setPage(page - 1)
}
}
})
}
const ComponentWithHistory = withRouter(MyComponent);
function App() {
return (
<BrowserRouter>
<Route path="/">
<ThemeProvider theme={theme}>
<ComponentWithHistory />
</ThemeProvider>
</Route>
</BrowserRouter>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)如果有更好的方法,我很想听;但这对我来说效果很好。
| 归档时间: |
|
| 查看次数: |
7619 次 |
| 最近记录: |