你不知道的 React Router 4
本篇文章不是把 不过,在阅读下文之前,你得首先保证以下的
如果你就是那 一个全新的 API
在 import React from "react";
import { render } from "react-dom";
import { Router,Route,IndexRoute,Link,browserHistory } from "react-router";
const PrimaryLayout = props =>
<div className="primary-layout">
<header>Our React Router 3 App</header>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/user">User</Link>
</li>
</ul>
<main>
{props.children}
</main>
</div>;
const HomePage = () => <h1>Home Page</h1>;
const UsersPage = () => <h1>User Page</h1>;
const App = () =>
<Router history={browserHistory}>
<Route path="/" component={PrimaryLayout}>
<IndexRoute component={HomePage} />
<Route path="/user" component={UsersPage} />
</Route>
</Router>;
render(<App />,document.getElementById("root"));
上面代码中有几个关键的点在
我们使用 import React from "react";
import { render } from "react-dom";
import { BrowserRouter,Link } from "react-router-dom";
const PrimaryLayout = () =>
<div className="primary-layout">
<header>Our React Router 4 App</header>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/User">User</Link>
</li>
</ul>
<main>
<Route path="/" exact component={HomePage} />
<Route path="/user" component={UsersPage} />
</main>
</div>;
const HomePage = () => <h1>Home Page</h1>;
const UsersPage = () => <h1>User Page</h1>;
const App = () =>
<BrowserRouter>
<PrimaryLayout />
</BrowserRouter>;
render(<App />,document.getElementById("root"));
接下来,我们用肉眼就能看出很多的变化,首先, 另外, Inclusive Routing在上面的 还是使用上面的
为了演示 const PrimaryLayout = () =>
<div className="primary-layout">
<header>
Our React Router 4 App
<Route path="/user" component={UsersMenu} />
</header>
<main>
<Route path="/" exact component={HomePage} />
<Route path="/user" component={UsersPage} />
</main>
</div>;
现在,当访问 Exclusive Routing如果你只想匹配一个 const PrimaryLayout = () =>
<div className="primary-layout">
<PrimaryHeader />
<main>
<Switch>
<Route path="/" exact component={HomePage} />
<Route path="/user/add" component={UserAddPage} />
<Route path="/user" component={UsersPage} />
<Redirect to="/" />
</Switch>
</main>
</div>;
在 当然,如果我们给每一个
"Index Routes" 和 "Not Found"
嵌套布局接下来,你可能很想知道 现在,我们假设我们要增加两个 第一种,如下修改 const PrimaryLayout = props => {
return (
<div className="primary-layout">
<PrimaryHeader />
<main>
<Switch>
<Route path="/" exact component={HomePage} />
<Route path="/user" exact component={BrowseUsersPage} />
<Route path="/user/:userId" component={UserProfilePage} />
<Route path="/products" exact component={BrowseProductsPage} />
<Route path="/products/:productId" component={ProductProfilePage} />
<Redirect to="/" />
</Switch>
</main>
</div>
);
};
虽然这种方法可以实现,但仔细观察下面的两个 const BrowseUsersPage = () => (
<div className="user-sub-layout">
<aside>
<UserNav />
</aside>
<div className="primary-content">
<BrowseUserTable />
</div>
</div>
)
const UserProfilePage = props => (
<div className="user-sub-layout">
<aside>
<UserNav />
</aside>
<div className="primary-content">
<UserProfile userId={props.match.params.userId} />
</div>
</div>
)
估计大家都发现了吧,两个 接下来,我们再看看 const PrimaryLayout = props => {
return (
<div className="primary-layout">
<PrimaryHeader />
<main>
<Switch>
<Route path="/" exact component={HomePage} />
<Route path="/user" component={UserSubLayout} />
<Route path="/products" component={ProductSubLayout} />
<Redirect to="/" />
</Switch>
</main>
</div>
);
};
我们用
使用这种策略,子布局也开始承担起了渲染 const UserSubLayout = () =>
<div className="user-sub-layout">
<aside>
<UserNav />
</aside>
<div className="primary-content">
<Switch>
<Route path="/user" exact component={BrowseUsersPage} />
<Route path="/user/:userId" component={UserProfilePage} />
</Switch>
</div>
</div>;
现在是不是解决了第一种方式中的 但有一点值得注意的是, const UserSubLayout = props =>
<div className="user-sub-layout">
<aside>
<UserNav />
</aside>
<div className="primary-content">
<Switch>
<Route path={props.match.path} exact component={BrowseUsersPage} />
<Route
path={`${props.match.path}/:userId`}
component={UserProfilePage}
/>
</Switch>
</div>
</div>;
Match正如我们上面看到的那样,
match.path vs match.url最开始,可能觉得这两者的区别并不明显,控制台经常出现相同的输出,比如,访问 const UserSubLayout = ({ match }) => {
console.log(match.url) // output: "/user"
console.log(match.path) // output: "/user"
return (
<div className="user-sub-layout">
<aside>
<UserNav />
</aside>
<div className="primary-content">
<Switch>
<Route path={match.path} exact component={BrowseUsersPage} />
<Route path={`${match.path}/:userId`} component={UserProfilePage} />
</Switch>
</div>
</div>
)
}
虽然我们看不到什么明显的差异,但需要明白的是 如何选择如果我们是构建 为了说明问题,我们创建两个子组件,一个 const UserComments = ({ match }) =>
<div>
UserId: {match.params.userId}
</div>;
const UserSettings = ({ match }) =>
<div>
UserId: {match.params.userId}
</div>;
const UserProfilePage = ({ match }) =>
<div>
User Profile:
<Route path={`${match.url}/comments`} component={UserComments} />
<Route path={`${match.path}/settings`} component={UserSettings} />
</div>;
然后,我们按下面方式来访问
实践后,我们发现,访问 正如
避免 Match Collisions假设我们的 const UserSubLayou = ({ match }) =>
<div className="user-sub-layout">
<aside>
<UserNav />
</aside>
<div className="primary-content">
<Switch>
<Route exact path={match.path} component={BrowseUsersPage} />
<Route path={`${match.path}/add`} component={AddUserPage} />
<Route path={`${match.path}/:userId/edit`} component={EditUserPage} />
<Route path={`${match.path}/:userId`} component={UserProfilePage} />
</Switch>
</div>
</div>;
现在,看清楚这个 另外,我们使用 Authorized Route在应用程序中 class App extends React.Component {
render() {
return (
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route path="/auth" component={UnauthorizedLayout} />
<AuthorizedRoute path="/app" component={PrimaryLayout} />
</Switch>
</BrowserRouter>
</Provider>
)
}
}
现在,我们首先会去选择应用程序在哪个 下面就是我写的 class AuthorizedRoute extends React.Component {
componentWillMount() {
getLoggedUser();
}
render() {
const { component: Component,pending,logged,...rest } = this.props;
return (
<Route
{...rest}
render={props => {
if (pending) return <div>Loading...</div>;
return logged
? <Component {...this.props} />
: <Redirect to="/auth/login" />;
}}
/>
);
}
}
const stateToProps = ({ loggedUserState }) => ({
pending: loggedUserState.pending,logged: loggedUserState.logged
});
export default connect(stateToProps)(AuthorizedRoute);
点击 这里 可以查看的我的整个 总结
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
