最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Router v4 Modal - Stack Overflow

programmeradmin3浏览0评论

I know how to do it in previous versions of React Router but I absolutely do not know how to do it in new React Router v4. Can somebody help me?

What do I want?

  1. When you type /image/1 in browser url, page will appear as normal.
  2. When you click on <Link>Image as modal</Link> with state modal: true, modal with image will appear BUT behind modal must be the previous content + url in browser === /image/1... Then If you press F5, page will appear as normal.

Example: instagram... etc

What do I think I'm doing wrong?

  1. I do not know how to display the previous content. That is all I guess.

Code:

const Images = (props) => {
  return (
    <div>
      <h2>Images</h2>
      <ul>
        <li><Link to={{
          pathname: '/image/1',
          state: {
            modal: true
          }
        }}>Image as modal</Link></li>
        <li><Link to="/image/2">Image</Link></li>
      </ul>
    </div>
  )
}

const Image = (props) => {
  return (
    <div>
      <h2>Image {props.match.params.id}</h2>
      <ul>
        <li><Link to="/images">Back to Images</Link></li>
      </ul>
    </div>
  )
}

ReactDOM.render(
  <Provider store={store}>
    <Router>
      <div>
        <Route path='/images' ponent={Images} />
        <Route path='/image/:id' ponent={Image} />
      </div>
    </Router>
  </Provider>,
  document.getElementById('digital')
)

I know how to do it in previous versions of React Router but I absolutely do not know how to do it in new React Router v4. Can somebody help me?

What do I want?

  1. When you type /image/1 in browser url, page will appear as normal.
  2. When you click on <Link>Image as modal</Link> with state modal: true, modal with image will appear BUT behind modal must be the previous content + url in browser === /image/1... Then If you press F5, page will appear as normal.

Example: instagram... etc

What do I think I'm doing wrong?

  1. I do not know how to display the previous content. That is all I guess.

Code:

const Images = (props) => {
  return (
    <div>
      <h2>Images</h2>
      <ul>
        <li><Link to={{
          pathname: '/image/1',
          state: {
            modal: true
          }
        }}>Image as modal</Link></li>
        <li><Link to="/image/2">Image</Link></li>
      </ul>
    </div>
  )
}

const Image = (props) => {
  return (
    <div>
      <h2>Image {props.match.params.id}</h2>
      <ul>
        <li><Link to="/images">Back to Images</Link></li>
      </ul>
    </div>
  )
}

ReactDOM.render(
  <Provider store={store}>
    <Router>
      <div>
        <Route path='/images' ponent={Images} />
        <Route path='/image/:id' ponent={Image} />
      </div>
    </Router>
  </Provider>,
  document.getElementById('digital')
)
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Feb 23, 2017 at 7:09 AltaulaAltaula 7841 gold badge8 silver badges25 bronze badges 2
  • What was your solution for the previous version of React-router? – Sasha Kastsiushkin Commented Mar 24, 2017 at 17:20
  • 3 @SashaKastsiushkin They fixed the problem in v4. So you can make modals in current version of router. Here is example: reacttraining./react-router/web/example/modal-gallery – Altaula Commented Mar 24, 2017 at 21:24
Add a ment  | 

3 Answers 3

Reset to default 8

I had the same problem, so I created:

http://npmjs./package/react-router-modal

It allows you to attach modals to routes. You would use it as follows:

import { ModalContainer, ModalRoute } from 'react-router-modal';
// ... 
ReactDOM.render(
  <Provider store={store}>
    <Router>
      <div>
        <Route path='/images' ponent={Images} />
        <ModalRoute path='/image/:id' ponent={Image} />
      </div>
    </Router>
    <ModalContainer />
  </Provider>,
  document.getElementById('digital')
)

There are a few simple examples at https://davidmfoley.github.io/react-router-modal-examples/

Hope it helps.

I was able to use the solution described here, which refers to this code example:

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

// This example shows how to render two different screens
// (or the same screen in a different context) at the same url,
// depending on how you got there.
//
// Click the colors and see them full screen, then "visit the
// gallery" and click on the colors. Note the URL and the ponent
// are the same as before but now we see them inside a modal
// on top of the old screen.

class ModalSwitch extends React.Component {
  // We can pass a location to <Switch/> that will tell it to
  // ignore the router's current location and use the location
  // prop instead.
  //
  // We can also use "location state" to tell the app the user
  // wants to go to `/img/2` in a modal, rather than as the
  // main page, keeping the gallery visible behind it.
  //
  // Normally, `/img/2` wouldn't match the gallery at `/`.
  // So, to get both screens to render, we can save the old
  // location and pass it to Switch, so it will think the location
  // is still `/` even though its `/img/2`.
  previousLocation = this.props.location;

  ponentWillUpdate(nextProps) {
    let { location } = this.props;

    // set previousLocation if props.location is not modal
    if (
      nextProps.history.action !== "POP" &&
      (!location.state || !location.state.modal)
    ) {
      this.previousLocation = this.props.location;
    }
  }

  render() {
    let { location } = this.props;

    let isModal = !!(
      location.state &&
      location.state.modal &&
      this.previousLocation !== location
    ); // not initial render

    return (
      <div>
        <Switch location={isModal ? this.previousLocation : location}>
          <Route exact path="/" ponent={Home} />
          <Route path="/gallery" ponent={Gallery} />
          <Route path="/img/:id" ponent={ImageView} />
        </Switch>
        {isModal ? <Route path="/img/:id" ponent={Modal} /> : null}
      </div>
    );
  }
}

const IMAGES = [
  { id: 0, title: "Dark Orchid", color: "DarkOrchid" },
  { id: 1, title: "Lime Green", color: "LimeGreen" },
  { id: 2, title: "Tomato", color: "Tomato" },
  { id: 3, title: "Seven Ate Nine", color: "#789" },
  { id: 4, title: "Crimson", color: "Crimson" }
];

function Thumbnail({ color }) {
  return (
    <div
      style={{
        width: 50,
        height: 50,
        background: color
      }}
    />
  );
}

function Image({ color }) {
  return (
    <div
      style={{
        width: "100%",
        height: 400,
        background: color
      }}
    />
  );
}

function Home() {
  return (
    <div>
      <Link to="/gallery">Visit the Gallery</Link>
      <h2>Featured Images</h2>
      <ul>
        <li>
          <Link to="/img/2">Tomato</Link>
        </li>
        <li>
          <Link to="/img/4">Crimson</Link>
        </li>
      </ul>
    </div>
  );
}

function Gallery() {
  return (
    <div>
      {IMAGES.map(i => (
        <Link
          key={i.id}
          to={{
            pathname: `/img/${i.id}`,
            // this is the trick!
            state: { modal: true }
          }}
        >
          <Thumbnail color={i.color} />
          <p>{i.title}</p>
        </Link>
      ))}
    </div>
  );
}

function ImageView({ match }) {
  let image = IMAGES[parseInt(match.params.id, 10)];

  if (!image) return <div>Image not found</div>;

  return (
    <div>
      <h1>{image.title}</h1>
      <Image color={image.color} />
    </div>
  );
}

function Modal({ match, history }) {
  let image = IMAGES[parseInt(match.params.id, 10)];

  if (!image) return null;

  let back = e => {
    e.stopPropagation();
    history.goBack();
  };

  return (
    <div
      onClick={back}
      style={{
        position: "absolute",
        top: 0,
        left: 0,
        bottom: 0,
        right: 0,
        background: "rgba(0, 0, 0, 0.15)"
      }}
    >
      <div
        className="modal"
        style={{
          position: "absolute",
          background: "#fff",
          top: 25,
          left: "10%",
          right: "10%",
          padding: 15,
          border: "2px solid #444"
        }}
      >
        <h1>{image.title}</h1>
        <Image color={image.color} />
        <button type="button" onClick={back}>
          Close
        </button>
      </div>
    </div>
  );
}

function ModalGallery() {
  return (
    <Router>
      <Route ponent={ModalSwitch} />
    </Router>
  );
}

export default ModalGallery;

a simple modal route example with javascript that can use with any routing system

<button onClick={() => {
    this.setState({ modal: true });
    window.history.pushState("","","/gallery/image/img_1233")
}}>
    Open Modal
</button>

//Link Button
<Link href="/gallery/image/img_1233">
    <a>Open Page</a>
</Link>

plete example here: https://github./mohammad-amin-hesam/react-modal-route-example

发布评论

评论列表(0)

  1. 暂无评论