- 学习资源推荐
react-router-dom官方示例解读(下)
Sidebar 侧边栏
分析
侧边栏这个案例很常见,官方示例里边介绍的除了基础侧边栏,还扩展了一种多处渲染的方式。即当路由匹配到当前url时,可以在应用给程序内任何你想渲染的地方去分别渲染sideber和main,注意下边的map遍历,只有children属性那里有差异
import React from "react";
import {render} 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>
}
];
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) => (
<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>
);
}
render(<SidebarExample/>,document.getElementById("root"))
效果图
- 结合效果图来看,侧边栏底部和右侧,都进行了渲染,即多处渲染。注意,这两次其实除了渲染的组件不同,其他都一样
config 路由配置
分析
有时候,也许你希望将路由集中配置,比如放在一个数组里,每个路由对象包含path和component。涉及嵌套的,就再来一个数组,存放子路由对象。
import React from "react";
import { render } from 'react-dom'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
const Sandwiches = () => <h2>Sandwiches</h2>
const Bus = () => <h2>Bus</h2>
const Cart = () => <h2>Cart</h2>
const routes = [
{
path: "/sandwiches",
component: Sandwiches
},
{
path: "/tacos",
component: Tacos,
routes: [
{
path: "/tacos/bus",
component: Bus
},
{
path: "/tacos/cart",
component: Cart
}
]
}
];
export default function App() {
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>
);
}
function RouteWithSubRoutes(route) {
return (
<Route
path={route.path}
render={(props) => {
return <route.component {...props} routes={route.routes} />
}}
/>
);
}
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>
);
}
render(<App />, document.getElementById("root"))
Query parameters 查询参数
分析
该示例其实本质是借用了浏览器内置的URLSearchParams,这个方法可以很方便的解析url参数,但这个存在兼容问题,放弃IE家族就没问题了。具体URLSearchParamsAPI,可参考MDN这段示例代码:
var paramsString = "q=URLUtils.searchParams&topic=api"
var searchParams = new URLSearchParams(paramsString);
searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"
import React from "react";
import { render } from 'react-dom'
import {
BrowserRouter as Router,
Link,
useLocation
} from "react-router-dom";
export default function App() {
return (
<Router>
<QueryParamsDemo />
</Router>
);
}
//这里是重点
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>
);
}
render(<App />, document.getElementById("root"))