隨着單頁應用的發展,路由這個詞不斷出如今咱們的視線中,路由跳轉,嵌套路由,路由配置,路由懶加載等等,目前整理了業界的一些面試題,帶着問題去整理咱們須要學習的知識,面試題主要是react技術棧的,以下html
window.location.hash = 'product' // 設置 url 的 hash,會在當前url後加上 '#product' console.log(window.location.hash) // '#product' // 監聽hash變化,點擊瀏覽器的前進後退會觸發 window.addEventListener('hashchange', function(){ }) // 或者在body上加上onhashchange <body onhashchange="myFunction()">
Hash history 使用 URL 中的 hash(#)部分去建立形如 example.com/#/some/path 的路由。前端
History 接口容許操做瀏覽器的曾經在標籤頁或者框架裏訪問的會話歷史記錄(相似棧對象)。經常使用Api以下html5
前往上一頁, 用戶可點擊瀏覽器左上角的返回按鈕模擬此方法. 等價於 history.go(-1).react
在瀏覽器歷史記錄裏前往下一頁,用戶可點擊瀏覽器左上角的前進按鈕模擬此方法. 等價於 history.go(1).git
經過當前頁面的相對位置從瀏覽器歷史記錄( 會話記錄 )加載頁面。github
按指定的名稱和URL(若是提供該參數)將數據push進會話歷史棧,數據被DOM進行不透明處理;面試
附加window apitypescript
window.onpopstate是popstate事件在window對象上的事件處理程序.
每當處於激活狀態的歷史記錄條目發生變化時,popstate事件就會在對應window對象上觸發. 若是當前處於激活狀態的歷史記錄條目是由history.pushState()方法建立,或者由history.replaceState()方法修改過的, 則popstate事件對象的state屬性包含了這個歷史記錄條目的state對象的一個拷貝. npm
調用history.pushState()或者history.replaceState()不會觸發popstate事件. popstate事件只會在瀏覽器某些行爲下觸發, 好比點擊後退、前進按鈕(或者在JavaScript中調用history.back()、history.forward()、history.go()方法).redux
目前咱們是基於create-react-app腳手架搭建起來的項目簡單配置的,直接上代碼
npx create-react-app my-app --typescript npm install --save react-router-dom
declare module "react-router-dom";
// Layout.tsx import * as React from "react"; import RouteView, { IRouteViewProps } from "../routes/RouteView"; import { History } from "history"; interface ILayoutProps extends IRouteViewProps { history: History; } const Layout = (props: ILayoutProps) => { const handleClick = React.useCallback((e) => { const { name } = e.target; props.history.push(name); }, [props.history]); return ( <div> <div> <button name="/basic/page1" onClick={handleClick}> Page1 </button> <button name="/basic/page2" onClick={handleClick}> Page2 </button> <button name="/basic/page3" onClick={handleClick}> Page3 </button> </div> <RouteView {...props} /> </div> ); }; export default Layout; // Page1.tsx import * as React from "react"; const Page1 = () => { return ( <div>我是Page1</div> ) }; export default Page1; // Page2.tsx import * as React from "react"; const Page2 = () => { return ( <div>我是Page2</div> ) }; export default Page2; // Page3.tsx import * as React from "react"; const Page3 = () => { return ( <div>我是Page3</div> ) }; export default Page3;
// router.config.ts import Layout from "../pages/Layout"; import { lazy } from "react"; const RouteConfig = [ { path: "/basic", component: Layout, children: [ { path: "/basic/page1", component: lazy(() => import("../pages/Page1")), }, { path: "/basic/page2", component: lazy(() => import("../pages/Page2")), }, { path: "/basic/page3", component: lazy(() => import("../pages/Page3")), }, { path: "/basic", redirect: "/basic/page1" }, ], }, // { // path: "/login", // component: lazy(() => import("../pages/Login")), // }, { path: "/", redirect: "/basic", }, ]; export default RouteConfig; // RouteView.tsx import React from "react"; import { Redirect, Route, Switch } from "react-router-dom"; export interface IRouteViewProps { path?: string; redirect?: string; component?: any; children?: IRouteViewProps[]; } const RouteView = (props: IRouteViewProps) => { return ( <Switch> {props.children && props.children.map((item, index) => { if (item.redirect) { return ( <Redirect key={index} from={item.path} to={item.redirect} ></Redirect> ); } return ( <Route key={index} path={item.path} render={(props) => { return ( item.component && ( <item.component children={item.children} {...props} ></item.component> ) ); }} ></Route> ); })} </Switch> ); }; export default RouteView;
// App.tsx import React, { Suspense } from "react"; import RouteConfig from "./routes/router.config"; import RouteView from "./routes/RouteView"; import { BrowserRouter } from "react-router-dom"; const App = () => { return ( <BrowserRouter> <Suspense fallback={<div>loading...</div>}> <RouteView children={RouteConfig}></RouteView> </Suspense> </BrowserRouter> ); }; export default App;
一個具有路由嵌套,路由懶加載,可配置化的的React-Router就配置好了,代碼請參考:https://github.com/wwlh200/re...
const {history} = props; history.push("/basic/product");
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(Product)); const {history} = props; history.push("/basic/other");
import { useHistory } from "react-router-dom"; function HomeButton() { let history = useHistory(); function handleClick() { history.push("/home"); } return ( <button type="button" onClick={handleClick}> Go home </button> ); }
const Component = React.lazy(() => import('./Component'));
缺點:不支持服務端渲染
// 第一步 npm install @loadable/component // 第二步 const Component = loadable(() => import('./Component'));
缺點:須要引入第三方包
import Loadable from "react-loadable"; export default function asyncComponent(comp) { return Loadable({ loader: comp, loading: (props) => { return "加載中..."; }, }); } import asyncComponent from "../utils/utils"; const Component = asyncComponent(() => import('./Component'));
缺點:該方法不建議使用,StrictMode下回報以下警告: The old API will be supported in all 16.x releases, but applications using it should migrate to the new version.