你不知道的 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); 点击 这里 可以查看的我的整个 总结
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |