React JS: How do I redirect back to my main page when user refreshes another particular page?

Viewed 863

I currently set up a simple React JS application with 2 pages - A landing page and a 'Room' page. I am using the useHistory hook from react-router.

Expected behavior

When user clicks refresh in the 'Room' page, the application shall go back to the 'Landing' page.

Projected behavior

User hits refresh, pathname did change to the pathname of the Landing page for a split second. And the 'Room' page mounted itself again, replacing the 'Landing' page.

Here are the code snippets of my application:

App.js

import LandingPage from './components/pages/LandingPage';
import RoomPage from './components/pages/RoomPage';

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={LandingPage}/>
        <Route path="/room-:roomId" component={RoomPage}/>
      </Switch>
    </Router>
  );
}

export default App;

Landing Page

function LandingPage(){
    const history = useHistory();

    function toRoomPage(){
        history.push('/room-{room_id here}');
    }

    function onAnotherBtnClick(){
        console.log("hi");
    }

    return (
        <div className="landing-page-container page-container">
            <div className="landing-page-inner-panel">
                <div className="landing-page-inner-top">
                    Landing Page
                </div>
                <div className="landing-page-button-wrapper">
                    <button className="btn btn-primary" onClick={toRoomPage}>To Room Page</button>
                </div>
                <div>or</div>
                <div className="landing-page-button-wrapper">
                    <button className="btn btn-secondary" onClick={onAnotherBtnClick}>Another Button</button>
                </div>
            </div>
        </div>
    );
}

export default LandingPage;

Room Page

function RoomPage(){
    const history = useHistory();

    function onUnload(){
        history.replace("/");
    }

    useEffect(() => {
        window.addEventListener("unload", onUnload)

        return () => {
            window.removeEventListener("unload", onUnload);
        }
    }, [])

    return (
        <div className="room-page-container page-container">
            Room Page
        </div>
    );
}

export default RoomPage;

I'm not too sure how the DOM behaves on refresh, as I am fairly new to React JS. I've tried both .replace() and .push(), but it still doesn't work.

I've been searching through the web for 2 hours straight, yet to no avail. Hopefully someone could give me some light. Thanks a lot in advance.

2 Answers

You need to check if the location path is room inside App.js useEffect without any params (It runs first time and when user refresh the page) then you can check if the route is different then redirect , but for that you need to change A few things in code , I will list the steps

1.You need to bind App.js with BrowserRouter inside index.js

import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>,
  rootElement
);


2.use hooks useLocation to check the route(pathname) and useHistory to redirect , useEffect to check if user has reloaded the page Code


import { Switch, Route, Link } from "react-router-dom";
import LandingPage from './components/pages/LandingPage';
import RoomPage from './components/pages/RoomPage';
import { useEffect } from "react";
import { useLocation, useHistory } from "react-router-dom";

export default function App(props) {
  const location = useLocation();
  const history = useHistory();
  useEffect(() => {
    if (location.pathname == "/room") {
      history.push("/");
    }
  }, []);
  return (
    <div className="App">
      <Switch>
        <Route exact path="/" component={LandingPage}/>
        <Route path="/room-:roomId" component={RoomPage}/>
      </Switch>
    </div>
  );
}



3.Remove the replace you are doing inside Room page and landing page

I have used a sample Codesandbox for similar one , ref it if you need

Edit adoring-sun-dwnde

Here is the solution:

App.js

import { Switch, Route, BrowserRouter as Router } from "react-router-dom";

import LandingPage from "./LandingPage";
import RoomPage from "./RoomPage";

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={LandingPage} />
        <Route path="/room-:roomId" component={RoomPage} />
      </Switch>
    </Router>
  );
}

export default App;

LandingPage.js

import { useHistory } from "react-router-dom";

function LandingPage() {
  const history = useHistory();

  function toRoomPage() {
    history.push("/room-{room_id here}");
  }

  function onAnotherBtnClick() {
    console.log("hi");
  }

  return (
    <div className="landing-page-container page-container">
      <div className="landing-page-inner-panel">
        <div className="landing-page-inner-top">Landing Page</div>
        <div className="landing-page-button-wrapper">
          <button className="btn btn-primary" onClick={toRoomPage}>
            To Room Page
          </button>
        </div>
        <div>or</div>
        <div className="landing-page-button-wrapper">
          <button className="btn btn-secondary" onClick={onAnotherBtnClick}>
            Another Button
          </button>
        </div>
      </div>
    </div>
  );
}

export default LandingPage;

RoomPage.js

import { useHistory } from "react-router-dom";
import { useEffect } from "react";

function RoomPage() {
  const history = useHistory();

  function onUnload() {
    console.log("beforeunload");
    history.push("/");
  }

  useEffect(() => {
    window.addEventListener("beforeunload", onUnload);

    return () => {
      window.removeEventListener("beforeunload", onUnload);
    };
  }, []);

  return <div className="room-page-container page-container">Room Page</div>;
}

export default RoomPage;

CodeSandbox Live Demo

Related