I'm working on my diploma project web site. There is a button on the main page which makes a modal window with a login form pops up. Also there is a button on this login form which makes a login form toggle to a register form in the same modal window. I struggled routing login modal window and register modal window.
MainPage.js
import React, { useState } from "react";
import "../App.css";
import Footer from "../Components/Footer";
import Navbar from "../Components/Navbar";
import Button from "../Components/Button";
import ModalLogin from "../Components/ModalLogin";
import RegisterModal from "../Components/RegisterModal";
const MainPage = () => {
const [isModalOpen, setModalOpen] = useState(false);
const [isLoginForm, setLoginForm] = useState(true);
function authorize() {
setModalOpen(true);
setLoginForm(true);
}
function closeModal() {
setModalOpen(false);
}
function toggleForm() {
setLoginForm((prev) => !prev);
}
return (
<div className="app-container">
<div className="main-container">
<Navbar />
<div className="intro-section-container">
<h1>
Цифровая
<br />
образовательная платформа
<br />
“Название не придумал”
</h1>
<p>
Откройте дверь в мир музыки с нашим электронным дневником.
<br />
Присоединяйтесь прямо сейчас!
</p>
<div className="intro-buttons-container">
<Button color="button-primary" label="Войти" onClick={authorize} />
<Button color="button-outlined" label="Подключить школу" />
</div>
</div>
{isModalOpen &&
(isLoginForm ? (
<ModalLogin onToggleForm={toggleForm} onClose={closeModal} />
) : (
<RegisterModal onToggleForm={toggleForm} onClose={closeModal} />
))
}
</div>
<Footer />
</div>
);
};
export default MainPage;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import NoPage from './Pages/NoPage';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="*" element={<NoPage />} />
</Routes>
</BrowserRouter>
</React.StrictMode>
);
App.js
import "./App.css";
import MainPage from "./Pages/MainPage";
function App() {
return (
<MainPage />
);
}
export default App;
I've tried different ways routing these forms, but none worked.
I want to route them, so if I open login modal I need my address be like
"localhost:3000/login"
, or"localhost:3000/register"
when register modal window opened.
Import and use the useNavigate
hook to issue imperative navigation actions to the appropriate "/login"
and "/register"
URL paths when the modal UI is toggled. Use a useEffect
hook with a dependency on the state variables to effect the navigation actions when the states update.
import { useNavigate } from 'react-router-dom';
const MainPage = () => {
const navigate = useNavigate();
const [isModalOpen, setModalOpen] = useState(false);
const [isLoginForm, setLoginForm] = useState(true);
useEffect(() => {
if (isModalOpen) {
// Modal is open, redirect to login or register path
navigate(isLoginForm ? "/login" : "/register", { replace: true });
} else {
// Modal is closed, redirect back to home page path
navigate("/", { replace: true });
}
}, [isModalOpen, isLoginForm]);
function authorize() {
setModalOpen(true);
setLoginForm(true);
}
function closeModal() {
setModalOpen(false);
}
function toggleForm() {
setLoginForm((prev) => !prev);
}
return (
...
);
};
You'll need to update the router to render the MainPage
, e.g. App
on all these routes so the UI remains mounted and rendered.
Example:
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="/login" element={<App />} />
<Route path="/register" element={<App />} />
<Route path="*" element={<NoPage />} />
</Routes>
</BrowserRouter>