react router

官方文檔 https://react-router.docschina.org/web/guides/quick-starthtml

history 對象是可變的,所以咱們建議從 <Route> 的渲染選項中來訪問 location,而不是從 history.location 直接獲取。這樣作能夠保證 React 在生命週期中的鉤子函數正常執行,例如:前端

// locationChanged 將爲 true
const locationChanged = nextProps.location !== this.props.locationreact

// INCORRECT,由於 history 是可變的因此 locationChanged 將一直爲 false
const locationChanged = nextProps.history.location !== this.props.history.locationnginx

 

使用總結 https://www.cnblogs.com/V587Chinese/p/11507836.htmlweb

BrowserRouter和HashRouter
這二者能夠理解爲路由的做用域,全部的Link組件和Route組件都必須在其內部。兩者區別在於:後端

  • BrowserRouter中的URL指向真實的url,當頁面刷新(或直接操做url並回車)時,將產生指向該路徑的url請求,若是服務器端沒有配置該路徑,則返回404。
  • HashRouter中#後面的uri並非真實的請求路徑,對於後端來講,全都指向同一個地址。另外哈希歷史記錄不支持loaction.key和loaction.state,當經過state傳遞參數的時候,沒法從歷史記錄中獲取到,可能會致使頁面顯示異常。
  • 也就是說在瀏覽器地址欄中直接輸入 http://test.code.com/aboutBrowserRouter會匹配不了而報404(由於服務端nginx中只配置了test.code.com,BrowserRouter代碼中的路由並不會被服務端識別),而 http://test.code.com/#/aboutHashRouter會正常顯示about頁面(由於訪問的後端地址僅僅是test.code.com)。

在BrowserRouter模式下,如何在服務端配置呢?瀏覽器

  • Nginx配置(前端項目打包),將任何URL訪問都指向index.html
  • 後端服務配置(前端項目打包),將任何URL訪問都指向index.html
  • 開啓前端服務(須要進行Nginx反向代理)

Link標籤和a標籤,看到的效果是同樣的,但咱們推薦<Link>,使用它纔是單頁面應用,瀏覽器不會請求頁面;而使用a標籤,會從新請求頁面。服務器

導航守衛的實現(權限校驗)react-router

NavLink 和  PureComponent 一塊兒使用的時激活連接樣式不生效 https://www.cnblogs.com/wenruo/p/10321456.htmlapp

v4 v3區別及策略 https://zhuanlan.zhihu.com/p/28585911

一、嵌套佈局

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 UserSubLayout2 = 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>;
const UserSubLayou3 = ({ 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} />
<Route component={NoMatch} /> </Switch> </div> </div>;
// 注意上面的route順序,由於switch只匹配一個,須要將更精確的放到前面。另外一種方式是每個route都加exact精確匹配。

咱們用 2 個 routes 替換以前的 4 個 routes
注意,這裏咱們沒有再使用 exact,由於,咱們但願 /user 能夠匹配任何以 /user 開始的 route,products 同理。
使用這種策略,子佈局也開始承擔起了渲染 routes 的責任。避免兩個 user組件頁面中都有一個<UserNav />的重複渲染問題。

有一點值得注意的是,routes 須要識別它的完整路徑才能匹配,爲了減小咱們的重複輸入,咱們可使用 props.match.path來代替。match.url 是瀏覽器 URL 的一部分,match.path 是咱們爲 router 書寫的路徑

二、Authorized Route 路由權限控制

在應用程序中限制未登陸的用戶訪問某些路由是很是常見的,還有對於受權和未受權的用戶 UI 也可能大不同,爲了解決這樣的需求,咱們能夠考慮爲應用程序設置一個主入口,如/auth表示有權限相關操做,/app表示業務操做。
如今,咱們首先會去選擇應用程序在哪一個頂級佈局中,好比,/auth/login 和 /auth/forgot-password 確定在 UnauthorizedLayout 中,另外,當用戶登錄時,咱們將判斷全部的路徑都有一個 /app 前綴以確保是否登陸。若是用戶訪問 /app 開頭的頁面但並無登陸,咱們將會重定向到登陸頁面。示例:

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);

另外可參考:導航守衛的實現

相關文章
相關標籤/搜索