返回目录
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './example';
ReactDOM.render(
<App />,
document.getElementById('root')
);
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
// This site has 3 pages, all of which are rendered
// dynamically in the browser (not server rendered).
//
// Although the page does not ever refresh, notice how
// React Router keeps the URL up to date as you navigate
// through the site. This preserves the browser history,
// making sure things like the back button and bookmarks
// work properly.
export default function BasicExample() {
return (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/dashboard">Dashboard</Link></li>
</ul>
<hr />
{/*
A looks through all its children
elements and renders the first one whose path
matches the current URL. Use a any time
you have multiple routes, but you want only one
of them to render at a time
*/ }
<Switch>
<Route exact path="/"><Home /></Route>
<Route path="/about"><About /></Route>
<Route path="/dashboard"><Dashboard /></Route>
</Switch>
</div>
</Router>
);
}
// You can think of these components as "pages"
// in your app.
function Home() {
return (<div><h2>Home</h2></div>);
}
function About() {
return (<div><h2>About</h2></div>);
}
function Dashboard() {
return (<div><h2>Dashboard</h2></div>);
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams
} from "react-router-dom";
// Params are placeholders in the URL that begin
// with a colon, like the `:id` param defined in
// the route in this example. A similar convention
// is used for matching dynamic segments in other
// popular web frameworks like Rails and Express.
export default function ParamsExample() {
return (
<Router>
<div>
<h2>Accounts</h2>
<ul>
<li><Link to="/netflix">Netflix</Link></li>
<li><Link to="/zillow-group">Zillow Group</Link></li>
<li><Link to="/yahoo">Yahoo</Link></li>
<li><Link to="/modus-create">Modus Create</Link></li>
</ul>
<Switch>
<Route path="/:id" children={<Child />} />
</Switch>
</div>
</Router>
);
}
function Child() {
// We can use the `useParams` hook here to access
// the dynamic pieces of the URL.
let { id } = useParams();
return (
<div>
<h3>ID: {id}</h3>
</div>
);
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
useRouteMatch
} from "react-router-dom";
// Since routes are regular React components, they
// may be rendered anywhere in the app, including in
// child elements.
//
// This helps when it's time to code-split your app
// into multiple bundles because code-splitting a
// React Router app is the same as code-splitting
// any other React app.
export default function NestingExample() {
return (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr />
<Switch>
<Route exact path="/"><Home /></Route>
<Route path="/topics"><Topics /></Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return (<div><h2>Home</h2></div>);
}
function Topics() {
// The `path` lets us build paths that are
// relative to the parent route, while the `url` lets
// us build relative links.
let { path, url } = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li><Link to={`${url}/rendering`}>Rendering with React</Link></li>
<li><Link to={`${url}/components`}>Components</Link></li>
<li><Link to={`${url}/props-v-state`}>Props v. State</Link></li>
</ul>
<Switch>
<Route exact path={path}><h3>Please select a topic.</h3></Route>
<Route path={`${path}/:topicId`}><Topic /></Route>
</Switch>
</div>
);
}
function Topic() {
// The that rendered this component has a
// path of `/topics/:topicId`. The `:topicId` portion
// of the URL indicates a placeholder that we can
// get from `useParams()`.
let { topicId } = useParams();
return (<div><h3>{topicId}</h3></div>);
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
Redirect,
useHistory,
useLocation
} from "react-router-dom";
// This example has 3 pages: a public page, a protected
// page, and a login screen. In order to see the protected
// page, you must first login. Pretty standard stuff.
//
// First, visit the public page. Then, visit the protected
// page. You're not yet logged in, so you are redirected
// to the login page. After you login, you are redirected
// back to the protected page.
//
// Notice the URL change each time. If you click the back
// button at this point, would you expect to go back to the
// login page? No! You're already logged in. Try it out,
// and you'll see you go back to the page you visited
// just *before* logging in, the public page.
export default function AuthExample() {
return (
<Router>
<div>
<AuthButton />
<ul>
<li><Link to="/public">Public Page</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
<Switch>
<Route path="/public"><PublicPage /></Route>
<Route path="/login"><LoginPage /></Route>
<PrivateRoute path="/protected"><ProtectedPage /></PrivateRoute>
</Switch>
</div>
</Router>
);
}
const fakeAuth = {
isAuthenticated: false,
authenticate(cb) {
fakeAuth.isAuthenticated = true;
setTimeout(cb, 100); // fake async
},
signout(cb) {
fakeAuth.isAuthenticated = false;
setTimeout(cb, 100);
}
};
function AuthButton() {
let history = useHistory();
return fakeAuth.isAuthenticated ? (
<p>
Welcome!{" "}
<button
onClick={() => {
fakeAuth.signout(() => history.push("/"));
}}
>Sign out</button>
</p>
) : (
<p>You are not logged in.</p>
);
}
// A wrapper for that redirects to the login
// screen if you're not yet authenticated.
function PrivateRoute({ children, ...rest }) {
return (
<Route
{...rest}
render={({ location }) =>
fakeAuth.isAuthenticated ? (
children
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location }
}}
/>
)
}
/>
);
}
function PublicPage() {
return <h3>Public</h3>;
}
function ProtectedPage() {
return <h3>Protected</h3>;
}
function LoginPage() {
let history = useHistory();
let location = useLocation();
let { from } = location.state || { from: { pathname: "/" } };
let login = () => {
fakeAuth.authenticate(() => {
history.replace(from);
});
};
return (
<div>
<p>You must log in to view the page at {from.pathname}</p>
<button onClick={login}>Log in</button>
</div>
);
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch
} from "react-router-dom";
// This example show how you could create a custom
// that renders something special when the URL
// is the same as the one the points to.
export default function CustomLinkExample() {
return (
<Router>
<div>
<OldSchoolMenuLink
activeOnlyWhenExact={true}
to="/"
label="Home"
/>
<OldSchoolMenuLink to="/about" label="About" />
<hr />
<Switch>
<Route exact path="/"><Home /></Route>
<Route path="/about"><About /></Route>
</Switch>
</div>
</Router>
);
}
function OldSchoolMenuLink({ label, to, activeOnlyWhenExact }) {
let match = useRouteMatch({
path: to,
exact: activeOnlyWhenExact
});
return (
<div className={match ? "active" : ""}>
{match && "> "}
<Link to={to}>{label}</Link>
</div>
);
}
function Home() {
return (<div><h2>Home</h2></div>);
}
function About() {
return (<div><h2>About</h2></div>);
}
返回目录
import React, { useState } from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
Prompt
} from "react-router-dom";
// Sometimes you want to prevent the user from
// navigating away from a page. The most common
// use case is when they have entered some data
// into a form but haven't submitted it yet, and
// you don't want them to lose it.
export default function PreventingTransitionsExample() {
return (
<Router>
<ul>
<li><Link to="/">Form</Link></li>
<li><Link to="/one">One</Link></li>
<li><Link to="/two">Two</Link></li>
</ul>
<Switch>
<Route path="/" exact children={<BlockingForm />} />
<Route path="/one" children={<h3>One</h3>} />
<Route path="/two" children={<h3>Two</h3>} />
</Switch>
</Router>
);
}
function BlockingForm() {
let [isBlocking, setIsBlocking] = useState(false);
return (
<form
onSubmit={event => {
event.preventDefault();
event.target.reset();
setIsBlocking(false);
}}
>
<Prompt
when={isBlocking}
message={location =>
`Are you sure you want to go to ${location.pathname}`
}
/>
<p>
Blocking?{" "}
{isBlocking ? "Yes, click a link or the back button" : "Nope"}
</p>
<p>
<input
size="50"
placeholder="type something to block transitions"
onChange={event => {
setIsBlocking(event.target.value.length > 0);
}}
/>
</p>
<p>
<button>Submit to stop blocking</button>
</p>
</form>
);
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Route,
Link,
Switch,
Redirect,
useLocation
} from "react-router-dom";
// You can use the last in a as a kind of
// "fallback" route, to catch 404 errors.
//
// There are a few useful things to note about this example:
//
// - A renders the first child that matches
// - A may be used to redirect old URLs to new ones
// - A export default function NoMatchExample() {
return (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/old-match">Old Match, to be redirected</Link></li>
<li><Link to="/will-match">Will Match</Link></li>
<li><Link to="/will-not-match">Will Not Match</Link></li>
<li><Link to="/also/will/not/match">Also Will Not Match</Link></li>
</ul>
<Switch>
<Route exact path="/"><Home /></Route>
<Route path="/old-match">
<Redirect to="/will-match" />
</Route>
<Route path="/will-match"><WillMatch /></Route>
<Route path="*"><NoMatch /></Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h3>Home</h3>;
}
function WillMatch() {
return <h3>Matched!</h3>;
}
function NoMatch() {
let location = useLocation();
return (<h3>No match for <code>{location.pathname}</code></h3>);
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
Redirect,
useParams,
useRouteMatch
} from "react-router-dom";
// Sometimes you don't know all the possible routes
// for your application up front; for example, when
// building a file-system browsing UI or determining
// URLs dynamically based on data. In these situations,
// it helps to have a dynamic router that is able
// to generate routes as needed at runtime.
//
// This example lets you drill down into a friends
// list recursively, viewing each user's friend list
// along the way. As you drill down, notice each segment
// being added to the URL. You can copy/paste this link
// to someone else and they will see the same UI.
//
// Then click the back button and watch the last
// segment of the URL disappear along with the last
// friend list.
export default function RecursiveExample() {
return (
<Router>
<Switch>
<Route path="/:id"><Person /></Route>
<Route path="/">
<Redirect to="/0" />
</Route>
</Switch>
</Router>
);
}
function Person() {
let { url } = useRouteMatch();
let { id } = useParams();
let person = find(parseInt(id));
return (
<div>
<h3>{person.name}’s Friends</h3>
<ul>
{person.friends.map(id => (
<li key={id}><Link to={`${url}/${id}`}>{find(id).name}</Link></li>
))}
</ul>
<Switch>
<Route path={`${url}/:id`}><Person /></Route>
</Switch>
</div>
);
}
const PEEPS = [
{ id: 0, name: "Michelle", friends: [1, 2, 3] },
{ id: 1, name: "Sean", friends: [0, 3] },
{ id: 2, name: "Kim", friends: [0, 1, 3] },
{ id: 3, name: "David", friends: [1, 2] }
];
function find(id) {
return PEEPS.find(p => p.id === id);
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
// Each logical "route" has two components, one for
// the sidebar and one for the main area. We want to
// render both of them in different places when the
// path matches the current URL.
// We are going to use this route config in 2
// spots: once for the sidebar and once in the main
// content section. All routes are in the same
// order they would appear in a .
const routes = [
{
path: "/",
exact: true,
sidebar: () => <div>home!</div>,
main: () => <h2>Home</h2>
},
{
path: "/bubblegum",
sidebar: () => <div>bubblegum!</div>,
main: () => <h2>Bubblegum</h2>
},
{
path: "/shoelaces",
sidebar: () => <div>shoelaces!</div>,
main: () => <h2>Shoelaces</h2>
}
];
export default function SidebarExample() {
return (
<Router>
<div style={{ display: "flex" }}>
<div
style={{
padding: "10px",
width: "40%",
background: "#f0f0f0"
}}
>
<ul style={{ listStyleType: "none", padding: 0 }}>
<li><Link to="/">Home</Link></li>
<li><Link to="/bubblegum">Bubblegum</Link></li>
<li><Link to="/shoelaces">Shoelaces</Link></li>
</ul>
<Switch>
{routes.map((route, index) => (
// You can render a in as many places
// as you want in your app. It will render along
// with any other s that also match the URL.
// So, a sidebar or breadcrumbs or anything else
// that requires you to render multiple things
// in multiple places at the same URL is nothing
// more than multiple s.
<Route
key={index}
path={route.path}
exact={route.exact}
children={<route.sidebar />}
/>
))}
</Switch>
</div>
<div style={{ flex: 1, padding: "10px" }}>
<Switch>
{routes.map((route, index) => (
// Render more s with the same paths as
// above, but different components this time.
<Route
key={index}
path={route.path}
exact={route.exact}
children={<route.main />}
/>
))}
</Switch>
</div>
</div>
</Router>
);
}
返回目录
styles.css
.fade-enter {
opacity: 0;
z-index: 1;
}
.fade-enter.fade-enter-active {
opacity: 1;
transition: opacity 250ms ease-in;
}
example.js
import "./styles.css";
import React from "react";
import {
TransitionGroup,
CSSTransition
} from "react-transition-group";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
Redirect,
useLocation,
useParams
} from "react-router-dom";
export default function AnimationExample() {
return (
<Router>
<Switch>
<Route exact path="/">
<Redirect to="/hsl/10/90/50" />
</Route>
<Route path="*">
<AnimationApp />
</Route>
</Switch>
</Router>
);
}
function AnimationApp() {
let location = useLocation();
return (
<div style={styles.fill}>
<ul style={styles.nav}>
<NavLink to="/hsl/10/90/50">Red</NavLink>
<NavLink to="/hsl/120/100/40">Green</NavLink>
<NavLink to="/rgb/33/150/243">Blue</NavLink>
<NavLink to="/rgb/240/98/146">Pink</NavLink>
</ul>
<div style={styles.content}>
<TransitionGroup>
{/*
This is no different than other usage of
, just make sure to pass
`location` to `Switch` so it can match
the old location as it animates out.
*/ }
<CSSTransition
key={location.key}
classNames="fade"
timeout={300}
>
<Switch location={location}>
<Route path="/hsl/:h/:s/:l" children={<HSL />} />
<Route path="/rgb/:r/:g/:b" children={<RGB />} />
</Switch>
</CSSTransition>
</TransitionGroup>
</div>
</div>
);
}
function NavLink(props) {
return (
<li style={styles.navItem}>
<Link {...props} style={{ color: "inherit" }} />
</li>
);
}
function HSL() {
let { h, s, l } = useParams();
return (
<div
style={{
...styles.fill,
...styles.hsl,
background: `hsl(${h}, ${s}%, ${l}%)`
}}
>
hsl({h}, {s}%, {l}%)
</div>
);
}
function RGB() {
let { r, g, b } = useParams();
return (
<div
style={{
...styles.fill,
...styles.rgb,
background: `rgb(${r}, ${g}, ${b})`
}}
>
rgb({r}, {g}, {b})
</div>
);
}
const styles = {};
styles.fill = {
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0
};
styles.content = {
...styles.fill,
top: "40px",
textAlign: "center"
};
styles.nav = {
padding: 0,
margin: 0,
position: "absolute",
top: 0,
height: "40px",
width: "100%",
display: "flex"
};
styles.navItem = {
textAlign: "center",
flex: 1,
listStyleType: "none",
padding: "10px"
};
styles.hsl = {
...styles.fill,
color: "white",
paddingTop: "20px",
fontSize: "30px"
};
styles.rgb = {
...styles.fill,
color: "white",
paddingTop: "20px",
fontSize: "30px"
};
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
// Some folks find value in a centralized route config.
// A route config is just data. React is great at mapping
// data into components, and is a component.
// Our route config is just an array of logical "routes"
// with `path` and `component` props, ordered the same
// way you'd do inside a ``.
const routes = [
{
path: "/sandwiches",
component: Sandwiches
},
{
path: "/tacos",
component: Tacos,
routes: [
{
path: "/tacos/bus",
component: Bus
},
{
path: "/tacos/cart",
component: Cart
}
]
}
];
export default function RouteConfigExample() {
return (
<Router>
<div>
<ul>
<li><Link to="/tacos">Tacos</Link></li>
<li><Link to="/sandwiches">Sandwiches</Link></li>
</ul>
<Switch>
{routes.map((route, i) => (
<RouteWithSubRoutes key={i} {...route} />
))}
</Switch>
</div>
</Router>
);
}
// A special wrapper for that knows how to
// handle "sub"-routes by passing them in a `routes`
// prop to the component it renders.
function RouteWithSubRoutes(route) {
return (
<Route
path={route.path}
render={props => (
// pass the sub-routes down to keep nesting
<route.component {...props} routes={route.routes} />
)}
/>
);
}
function Sandwiches() {
return <h2>Sandwiches</h2>;
}
function Tacos({ routes }) {
return (
<div>
<h2>Tacos</h2>
<ul>
<li><Link to="/tacos/bus">Bus</Link></li>
<li><Link to="/tacos/cart">Cart</Link></li>
</ul>
<Switch>
{routes.map((route, i) => (
<RouteWithSubRoutes key={i} {...route} />
))}
</Switch>
</div>
);
}
function Bus() {
return <h3>Bus</h3>;
}
function Cart() {
return <h3>Cart</h3>;
}
返回目录
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useHistory,
useLocation,
useParams
} 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 "featured images" and see them full screen. Then
// "visit the gallery" and click on the colors. Note the URL and
// the component are the same as before but now we see them
// inside a modal on top of the gallery screen.
export default function ModalGalleryExample() {
return (
<Router>
<ModalSwitch />
</Router>
);
}
function ModalSwitch() {
let location = useLocation();
// This piece of state is set when one of the
// gallery links is clicked. The `background` state
// is the location that we were at when one of
// the gallery links was clicked. If it's there,
// use it as the location for the so
// we show the gallery in the background, behind
// the modal.
let background = location.state && location.state.background;
return (
<div>
<Switch location={background || location}>
<Route exact path="/" children={<Home />} />
<Route path="/gallery" children={<Gallery />} />
<Route path="/img/:id" children={<ImageView />} />
</Switch>
{/* Show the modal when a background page is set */}
{background && <Route path="/img/:id" children={<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="/img/2">Tomato</Link></li>
<li><Link to="/img/4">Crimson</Link></li>
</ul>
</div>
);
}
function Gallery() {
let location = useLocation();
return (
<div>
{IMAGES.map(i => (
<Link
key={i.id}
to={{
pathname: `/img/${i.id}`,
// This is the trick! This link sets
// the `background` in location state.
state: { background: location }
}}
>
<Thumbnail color={i.color} />
<p>{i.title}</p>
</Link>
))}
</div>
);
}
function ImageView() {
let { id } = useParams();
let image = IMAGES[parseInt(id, 10)];
if (!image) return <div>Image not found</div>;
return (
<div>
<h1>{image.title}</h1>
<Image color={image.color} />
</div>
);
}
function Modal() {
let history = useHistory();
let { id } = useParams();
let image = IMAGES[parseInt(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>
);
}
返回目录
import React, { Component } from "react";
import { StaticRouter as Router, Route } from "react-router-dom";
// This example renders a route within a StaticRouter and populates its
// staticContext, which it then prints out. In the real world you would
// use the StaticRouter for server-side rendering:
//
// import express from "express";
// import ReactDOMServer from "react-dom/server";
//
// const app = express()
//
// app.get('*', (req, res) => {
// let staticContext = {}
//
// let html = ReactDOMServer.renderToString(
//
// (includes the RouteStatus component below e.g. for 404 errors)
//
// );
//
// res.status(staticContext.statusCode || 200).send(html);
// });
//
// app.listen(process.env.PORT || 3000);
function RouteStatus(props) {
return (
<Route
render={({ staticContext }) => {
// we have to check if staticContext exists
// because it will be undefined if rendered through a BrowserRouter
if (staticContext) {
staticContext.statusCode = props.statusCode;
}
return <div>{props.children}</div>;
}}
/>
);
}
function PrintContext(props) {
return <p>Static context: {JSON.stringify(props.staticContext)}</p>;
}
export default class StaticRouterExample extends Component {
// This is the context object that we pass to the StaticRouter.
// It can be modified by routes to provide additional information
// for the server-side render
staticContext = {};
render() {
return (
<Router location="/foo" context={this.staticContext}>
<div>
<RouteStatus statusCode={404}>
<p>Route with statusCode 404</p>
<PrintContext staticContext={this.staticContext} />
</RouteStatus>
</div>
</Router>
);
}
}
返回目录
//example.js
import React from "react";
import {
BrowserRouter as Router,
Link,
useLocation
} from "react-router-dom";
// React Router does not have any opinions about
// how you should parse URL query strings.
//
// If you use simple key=value query strings and
// you do not need to support IE 11, you can use
// the browser's built-in URLSearchParams API.
//
// If your query strings contain array or object
// syntax, you'll probably need to bring your own
// query parsing function.
export default function QueryParamsExample() {
return (
<Router>
<QueryParamsDemo />
</Router>
);
}
// A custom hook that builds on useLocation to parse
// the query string for you.
function useQuery() {
return new URLSearchParams(useLocation().search);
}
function QueryParamsDemo() {
let query = useQuery();
return (
<div>
<div>
<h2>Accounts</h2>
<ul>
<li><Link to="/account?name=netflix">Netflix</Link></li>
<li><Link to="/account?name=zillow-group">Zillow Group</Link></li>
<li><Link to="/account?name=yahoo">Yahoo</Link></li>
<li><Link to="/account?name=modus-create">Modus Create</Link></li>
</ul>
<Child name={query.get("name")} />
</div>
</div>
);
}
function Child({ name }) {
return (
<div>
{name ? (
<h3>
The <code>name</code> in the query string is "{name}
"
</h3>
) : (
<h3>There is no name in the query string</h3>
)}
</div>
);
}