Try not to use the React Router
import React from 'react';
import ReactDOM from 'react-dom';
const About = () = > {
return <div>About</div>;
};
const Inbox = () = > {
return <div>Inbox</div>;
};
const Home = () = > {
return <div>Home</div>;
};
const App = () = > {
const [hash, setHash] = React.useState(' ');
const updateMenu = () = > {
const hashValue = window.location.hash.replace(The '#'.' ') | |'home';
setHash(hashValue);
};
React.useEffect(() = > {
updateMenu();
window.addEventListener('hashchange', updateMenu);
return () = > {
window.removeEventListener('hashchange', updateMenu); }; } []);const renderChild = () = > {
let Child;
switch (hash) {
case '/about':
Child = About;
break;
case '/inbox':
Child = Inbox;
break;
default:
Child = Home;
}
return <Child />;
};
return (
<div>
<h1>App</h1>
<ul>
<li>
<a href="#/about">About</a>
</li>
<li>
<a href="#/inbox">Inbox</a>
</li>
</ul>
{renderChild()}
</div>
);
};
ReactDOM.render(<App />.document.body);
Copy the code
When the hash part of the URL changes,
renders a different
based on the hash. It seems straightforward, but it can get complicated quickly as the business evolves. To make our URL parsing smarter, we need to write a lot of code that specifies which nested UI component branches the URL should render.
Using the Router
import React from 'react';
import ReactDOM from 'react-dom';
import { Route, BrowserRouter, Link, Switch } from 'react-router-dom';
const About = () = > {
return <div>About</div>;
};
const Inbox = () = > {
return <div>Inbox</div>;
};
const home = () = > {
return <div>home</div>;
};
const App = () = > {
return (
<div>
<BrowserRouter>
<h1>App</h1>
<ul>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/inbox">Inbox</Link>
</li>
</ul>
<Switch>
<Route exact={true} path="/" component={home} />
<Route exact={true} path="/about" component={About} />
<Route exact={true} path="/inbox" component={Inbox} />
</Switch>
</BrowserRouter>
</div>
);
};
ReactDOM.render(<App />.document.body);
Copy the code
From the above configuration, the application knows how to render the following three urls
URL | component |
---|---|
/ |
home |
/about |
About |
/inbox |
Inbox |
The react – the router – dom example
URL Parameters
import React from 'react';
import ReactDOM from 'react-dom';
import { Route, BrowserRouter, Link, Switch, useParams } from 'react-router-dom';
const About = () = > {
return <div>About</div>;
};
const Inbox = () = > {
return <div>Inbox</div>;
};
const home = () = > {
return <div>home</div>;
};
const Child = () = > {
console.log('useParams:', useParams());
const { id } = useParams() as any;
return <div>ID: {ID}</div>;
};
const App = () = > {
return (
<div>
<BrowserRouter basename="test">
<h1>App</h1>
<ul>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/inbox">Inbox</Link>
</li>
<li>
<Link to="/child/yahoo">Yahoo</Link>
</li>
<li>
<Link to="/child/modus-create">Modus Create</Link>
</li>
</ul>
<Switch>
<Route exact={true} path="/" component={home} />
<Route exact={true} path="/about" component={About} />
<Route exact={true} path="/inbox" component={Inbox} />
<Route exact={true} path="/child/:id" children={<Child />} / ></Switch>
</BrowserRouter>
</div>
);
};
ReactDOM.render(<App />.document.body);
Copy the code
UseParams returns the key/value pair object of the URL parameter. Use it to access mate.params currently
.
Tip: key (ID) of the key/value pair object, corresponding to the ID of path=”/child/:id”, for example: path=”/child/:slug”, {slug: XXX}
Nesting
import React from 'react';
import ReactDOM from 'react-dom';
import { Route, BrowserRouter, Link, Switch, useParams, useRouteMatch } from 'react-router-dom';
const Topics = () = > {
console.log('useRouteMatch:', useRouteMatch());
const { 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>
);
};
const Topic = () = > {
const { topicId } = useParams() as any;
return (
<div>
<h3>{topicId}</h3>
</div>
);
};
const home = () = > {
return <div>home</div>;
};
const App = () = > {
return (
<div>
<BrowserRouter basename="test">
<h1>App</h1>
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/topics">topics</Link>
</li>
</ul>
<Switch>
<Route exact={true} path="/" component={home} />
<Route path="/topics" component={Topics} />
</Switch>
</BrowserRouter>
</div>
);
};
ReactDOM.render(<App />.document.body);
Copy the code
UseRouteMatch attempts to match the current URL in the same way as
. It is primarily used to access matching data without actually rendering
Pay attention to the use of exact
Redirect (authentication)
import React, { useContext, createContext, useState } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Switch, Route, Link, Redirect, useHistory, useLocation } from 'react-router-dom';
/* * Use createContext to pass data across components * first define a container and default values to pass in the parent, * then define shared data through a Provider, * then define shared data through a Consumer. Is a child component or grandson component to use), the specific implementation code is as follows: */
const authContext = createContext({});
const ProvideAuth = (props: any) = > {
// Returns a permission management object
const auth = useProvideAuth();
return <authContext.Provider value={auth}>{props.children}</authContext.Provider>;
};
// Hooks were added after react16.8. You can use useContext in hooks to get consumers
const useAuth = () = > {
return useContext(authContext);
};
// Used to manage permission to deliver data
const useProvideAuth = () = > {
const [user, setUser] = useState(null as null | string);
const signin = (cb: () => void) = > {
// Login operation
setUser('user');
// Operations performed after successful login
setTimeout(cb, 100);
};
const signout = (cb: () => void) = > {
// Exit the operation
setUser(null);
setTimeout(cb, 100);
};
return {
user,
signin,
signout,
};
};
const AuthButton = () = > {
let history = useHistory();
let auth = useAuth() as any;
return auth.user ? (
<p>Welcome!<br />User: {auth. User}<br />
<button
onClick={()= > {
auth.signout(() => history.push('/'));
}}
>
Sign out
</button>
</p>
) : (
<p>You are not logged in</p>
);
};
// Redirect to login
// If you are not authenticated, select Login
const PrivateRoute = (props: any) = > {
// Get permission data
let auth = useAuth() as any;
return (
<Route
{. props.rest} // Render if there is a user, otherwise redirectlogin
render={({ location}) = >
auth.user ? (
props.children
) : (
<Redirect
to={{
pathname: '/login',
state: { from: location}}} / >
)
}
/>
);
};
const PublicPage = () = > {
return <h3>Open the page</h3>;
};
const ProtectedPage = () = > {
return <h3>Protect the page</h3>;
};
function LoginPage() {
let history = useHistory();
let location = useLocation() as any;
let auth = useAuth() as any;
let { from } = location.state || { from: { pathname: '/'}};let login = () = > {
auth.signin(() = > {
history.replace(from);
});
};
return (
<div>
<p>You must be logged in to view this page {from.pathname}</p>
<button onClick={login}>Log in</button>
</div>
);
}
export default function AuthExample() {
return (
<ProvideAuth>
<Router>
<div>
<AuthButton />
<ul>
<li>
<Link to="/public">The public pages</Link>
</li>
<li>
<Link to="/protected">Protect pages</Link>
</li>
</ul>
<Switch>
<Route path="/public">
<PublicPage />
</Route>
<Route path="/login">
<LoginPage />
</Route>
<PrivateRoute path="/protected">
<ProtectedPage />
</PrivateRoute>
</Switch>
</div>
</Router>
</ProvideAuth>
);
}
ReactDOM.render(<AuthExample />.document.body);
Copy the code
Redirect Redirect. If Switch is used, put Redirect behind
<Route path="/home"
render={() = > (
<Switch>
<Route path="/home/page1" />
<Route path="/home/page2" />
<Redirect to="/home/page1" />
</Switch>)} / >Copy the code
No matching (404).
const NoMatch = () = > {
let location = useLocation();
return (
<div>
<h3>Not with the<code>{location.pathname}</code>Corresponding page, 404</h3>
</div>
);
};
<Switch>.<Route path="*" component={NoMatch} />
</Switch>
Copy the code
Path =”*”, render if there is no match. If you have a bottom pocket page, you can redirect to a 404 page
<Route render={() = > <Redirect to="/ 404" />} / >Copy the code
Sidebar
import React from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
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>}];const 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) => (
<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) => (
<Route
key={index}
path={route.path}
exact={route.exact}
children={<route.main />}} / >))</Switch>
</div>
</div>
</Router>
);
}
ReactDOM.render(<SidebarExample />.document.body);
Copy the code
Effect: