So if you want to use some global type state then I would use the new Context in the latest react like so...
...
React.useContext(SomeContext)
...
Read more here how you can use it and achieve a redux style app with it if you like.
Its a good read BUT STOP ....!!!!!!!!
I would not use that either to do what you want.
Really your url is(should) be the global state and it should contain everything you need to show sometimes that means refactoring how your urls and pages are structured.
In this example they pass model true though a state var, I try to avoid passing state though url link calls because if the user then refreshes the page on that url the state is lost and in this example there is a clear bug when doing that. So this is how i would achieve the same thing but using the url as king.
import React, { Component } from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
class ModalSwitch extends Component {
render() {
return (
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/gallery/:type?/:id?" component={Gallery} />
<Route path="/featured/img/:id" component={ImageView} />
</Switch>
<Route path="/gallery/img/:id" component={Modal} />
</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="/featured/img/2">Tomato</Link>
</li>
<li>
<Link to="/featured/img/4">Crimson</Link>
</li>
</ul>
</div>
);
}
function Gallery() {
return (
<div>
{IMAGES.map(i => (
<Link
key={i.id}
to={{
pathname: `/gallery/img/${i.id}`
}}
>
<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 component={ModalSwitch} />
</Router>
);
}
export default ModalGallery;
This is much simpler way. The key here is using variables in the Route path.
When we visit /gallery
we satisfy the Gallery path as we have said that the :type and :id are optional for this view.
So when we add the /gallery/img/0
we saying that this is a model as we want to lay it over the gallery and so we show both the Gallery and Modal components together.
But when we go to the /featured/img/0
it will only satisfy the ImageView
<Switch>
<Route exact path="/" component={Home} />
<Route path="/gallery/:type?/:id?" component={Gallery} />
<Route path="/featured/img/:id" component={ImageView} />
</Switch>
<Route path="/gallery/img/:id" component={Modal} />