如何在React SPA中使用函数组件和React Router v5拦截后退按钮?

问题描述 投票:0回答:1

我在React的SPA中工作,不使用React Router来创建任何Routes;我不需要让用户导航到特定的页面。想象一下多页的问卷,按顺序填写)。

但是,当用户按下返回按钮时 在浏览器上我不希望他们退出整个应用程序;我希望能够在用户按下后退按钮时启动一个功能,简单地将页面渲染成他们最后选择之前的样子。(每个页面都是一个组件,它们被组装在一个数组中,由一个叫做 currentPage 状态变量(来自状态钩子),所以我可以简单地呈现出这个 pages[currentPage -1].

使用(如果需要的话)当前版本的React Router(v5)、函数组件和Typescript,我怎样才能访问back-button事件,既禁用它,又用我自己的函数替换它?

我找到的其他答案要么使用类组件,要么使用React Router旧版本特有的函数,要么使用特定的框架,比如Next.js)。

任何和所有的见解都是感激的。

reactjs typescript react-router single-page-application
1个回答
0
投票

经过太多时间的努力,我找到了一个解决方案。由于最终找到了合适的路径,并不是那么困难,所以我把我的解决方案贴出来,希望可以节省别人的时间。

  1. 为web安装React Router,和类型--。npm install --save react-router-dom @types/react-router-dom.
  2. 进口 { BrowserRouter, Route, RouteComponentProps, withRouter }react-router-dom.
  3. 确定当按下后退按钮时,其状态将改变的组件。
  4. 传入 historyRouteComponentProps 通过解构。
    function MyComponent( { history }: ReactComponentProps) {
        ...
    }
    
  5. 在屏幕状态改变时(用户认为是一个新的页面),在下面增加一个空白条目。history;为例。

    function MyComponent( { history }: ReactComponentProps) {
    
        const handleClick() {
            history.push('')
        }
    
    }
    

    这将在历史记录中创建一个空白条目,所以历史记录中的条目可以被后退按钮访问;但用户看到的网址不会改变。

  6. 处理后退按钮时应发生的变化 在浏览器上 被按下。请注意,组件的生命周期方法,如 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.
            }
        }
    })
    
  7. 包在 withRouter 并创建一个可以访问路由属性的新组件。
    const ComponentWithHistory = withRouter(MyComponent);
    
  8. 现在把所有的东西都包在一个 <BrowserRouter /> 和a <Route /> 以便React Router将其识别为路由器,并将所有路径路由到 path="/",它将捕获所有的路由,除非指定了更多的特定路径的路由(无论如何,这些路径都是一样的,在这种设置下,由于 history.push(""); 历史将是这样的 ["", "", "", "", ""]).

    function App() {
    
    return (
        <BrowserRouter>
            <Route path="/">
                <ThemeProvider theme={theme}>
                    <ComponentWithHistory />
                </ThemeProvider>
            </Route>
        </BrowserRouter>
        );
    }
    
    export default App;
    
  9. 一个完整的例子现在看起来是这样的。

    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;
    

如果有更好的方法,我很乐意听到;但这对我来说非常有效。

© www.soinside.com 2019 - 2024. All rights reserved.