React(四)

URL的hash

  • 前端路由是如何做到URL和内容进行映射的呢?
    • 监听URL的改变
  • URL的hash
    • URL的hash也就是锚点(#),本质上是改变window.location的href属性
    • 我们可以通过直接赋值location.hash来改变href,但是页面不发生刷新
  • hashchange
  • hash的优势就是兼容性更好,在老版本IE中都可以运行,但是缺陷是有一个#,显得不像一个真实的路径

HTML5的History

  • history接口是HTML5新增的,它有六种模式改变URL而不刷新页面
    • replaceState:替换原来的路径
    • pushState:使用新的路径
    • popState:路径的回退
    • go:向前或者向后改变路径
    • forward:向前改变路径
    • back:向后改变路径

react-router

  • react-router-dom
    • 提供了一些组件
      • BrowserRouter
      • HashRouter
1
2
3
4
5
root.render(
<HashRouter>
<App />
</HashRouter>
)
  • 路由映射配置
    • Routes:包裹所有的Route,在其中匹配一个路由
      • Router5.x使用的是Switch组件
    • Route:Route用于路径的匹配
      • path属性:用于设置匹配到的路径
      • element属性:设置匹配到路径后,渲染的组件
        • Route5.x使用的是component属性
      • exact:精准匹配,只有精准匹配到完全一直的路径,才会渲染对应的组件
        • Router6.x不再支持该属性
  • 路由配置和跳转
    • Link和NavLink
      • 通常路径的跳转是使用Link组件,最终会被渲染成a元素
      • NavLink是在Link基础之上增加了一些样式属性
      • to属性:Link中用于设置跳转的路径
1
2
3
4
5
6
7
8
<Routes>
// 重定向
<Route path="/" element={<Navigate to='/home'/>}/>
<Route path="/home" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/custom/:id" element={<Custom />} /> // 动态路由
<Route path="*" element={<NotFound />} />
</Routes>
  • Navigate导航
    • Navigate用于路由的重定向,当这个组件出现时,就会执行跳转到对应的to路径中
1
2
3
4
{ !isLogin 
? <button onClick={e => this.state.isLogin = true}>登录</button>
: <Navigate to='/Dashboard'/>
}
  • 路由的嵌套
1
2
3
4
5
6
7
<Route path="/home" element={<Home />}>
<Route path="/home/homeOne" element={<HomeOne />}></Route>
<Route path="/home/homeTwo" element={<HomeTwo />}></Route>
</Route>

// home.jsx 用于在父路由元素中作为子路由的占位元素
<Outlet/>
  • 高阶组件:函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function withRouter(WrapperComponent){
// 类组件拿不到router信息
return function (props) {
// 导航
const navigate = useNavigate();

// 动态路由的参数
const params = useParams()

// 查询字符串的参数
const location = useLocation()

//Or
const [searchParams,setSearchParams] = useSearchParams()
const query = Object.fromEntries(searchParams.entries())

const router = { navigate, params, useLocation, query }
return <WrapperComponent {...props} router={router} />
}
}
  • 路由配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// router/index.js
const routes = [
{
path:'/',
element:<Navigate to='/home' />
},
{
path:'/home',
element:<Home/>,
children:[
{
path:'/home',
element:<Navigate to='/home/homeOne' />
},
{
path:'/home/homeTwo',
element:<HomeTwo/>
}
]
},
{
path:'/about',
element:<About/>
},
{
path:'*',
element:<NotFound/>
}
]

export default routes

// App.jsx
<div>
{useRoutes(routes)}
</div>
  • 路由懒加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const About = React.lazy(()=>import("../pages/About"))

const routes = [
{
path:'/about',
element:<About/>
}
]

root.render(
<HashRouter>
<Suspense fallBack={<h1>Loading...</h1>}>
<App/>
</Suspense>
</HashRouter>
)