[React] Create a Query Parameter Modal Route with React Router

Routes are some times better served as a modal. If you have a modal (like a login modal) that needs to be routeable and appear on all pages you may need to use query params. Will explore how to render a route all the time and use query params to control when it's content renders.

 

Modal should be created as a 'Portal':

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <div id="modal_root"></div>
</body>
import React, { Component } from "react";
import { createPortal } from "react-dom";

const modalStyle = {
  position: "fixed",
  left: 0,
  top: 0,
  bottom: 0,
  right: 0,
  backgroundColor: "rgba(0,0,0,.2)",
  color: "#FFF",
  fontSize: "40px",
};
export default class Modal extends Component {
  render() {
    return createPortal(
      <div style={modalStyle} onClick={this.props.onClick}>
        {this.props.children}
      </div>,
      document.getElementById("modal_root"),
    );
  }
}

 

If we want to show the Modal everywhere in the page, we need to declear the Router outside 'Switch' component:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";

import { BrowserRouter, Switch, Route } from "react-router-dom";
import HomePage from "./pages/home";
import ProfilePage from "./pages/profile";
import Login from "./pages/login";

const routes = (
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={HomePage} />
      <Route path="/profile" component={ProfilePage} />
    </Switch>
    <Route path="/" component={Login} />
  </BrowserRouter>
);

ReactDOM.render(routes, document.getElementById("root"));

For all the routes re-render, Login component will be shown.

 

Inside Login componnet, control the component show / hide by query param:

import React, { Component } from "react";
import Modal from "./modal";

export default class LoginPage extends Component {
  render() {
    let params = new URLSearchParams(this.props.location.search);

    return (
      params.get("login") && (
        <Modal
          onClick={() => {
            this.props.history.push(this.props.location.pathname);
          }}
        >
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              height: "100%",
            }}
          >
            Login modal
          </div>
        </Modal>
      )
    );
  }
}

 

Using:

<Link to={{ pathname: "/", search: "?login=true" }}>Login</Link>

 

上一篇:Bootstrap 使用弹窗 Modal 时页面抖动


下一篇:解决bootstrap modal中Dropzone already attached报错。