ReactRoutr6
- React Router以三个不同类型的包发布到npm上:
- react-router路由的核心库,提供了很多的组件、钩子
- react-router-dom:包含react-router所有内容,并添加一些专门用于DOM的组件,例如<BrowserRouter/>等
- react-router-native:包含react-router所有内容,并添加一些专门用于ReactNative的API,例如<NativeRouter/>等
- 与ReactRoutr5.x版本相比,改变了什么?
- 内置组件的变化:移除<Switch>,新增<Routes>等
- 语法的变化,component={About}变为element={<About/>}等
- 新增多个Hook:useParams、useNavigate、useMatch等
- 官方明确推荐函数式组件!!!
React Component
- <BrowserRouter>和<HashRouter>用法不变
- <Routes>与<Route>:
(1)v6版本移除了<Switch>,引入新的替代者<Routes>
(2)<Routes>和<Route>要配合使用,且必须要用<Routes>包裹<Route>
(3)<Routes>相当于一个if语句,如果其路径与当前URL匹配,则呈现其对应组件
(4)<Routes caseSensitive>属性用于指定匹配时是否区分大小写(默认false)
(5)<Route>可以嵌套使用,且可配合useRoutes()配置路由表,但需通过<Outlet>组件来渲染子路由<Routes> //path定义路径,element属性用于定义当前路径所对应的组件 <Route path="/about" element={<About/>}></Route> <Route path="/home" element={<Home/>}> <Route path="test" element={<Test/>}/></Route> </Route> <Route path="/" element={<Navigate to="/home" replace={false}/>}></Route> //Route也可以不写element属性,这时就可以用来展示嵌套的路由,所对应的路径是/users/xxx <Route path="users"> <Route pah="xxx" element={<Demo/>}><Route/> <Route/> <Route/> </Routes>
- <Link>和<NavLink>用法与v5一样,<NavLink>的高亮效果不再用activeClass
<NavLink className={({isActive })=>{ isActive ? 'active list-group-item' : 'list-group-item' } to="/about">About</NavLink> //默认情况下,当Home的子组件匹配成功,home的导航也会高亮 //当NavLink 上添加end属性后,若Home的子组件匹配成功,则home的导航不会高亮 <NavLink to="/home" end>Home</NavLink>
- <Link>和<NavLink>用法与v5一样,<NavLink>的高亮效果不再用activeClass
- <Navigate>
(1) 只要<Navigate>组件被渲染,就会修改路径,切换视图
(2) replace用于控制跳转模式(push 或 replace,默认push) - <Outlet>,当<Route>产生嵌套时,渲染其对应的子路由
React Hook
是什么?
- Hook是react16.8.0版本增加的新特性/新语法
- 可以让你在函数组件中使用state以及其他的react特性(因函数式组件没有this,所以没有生命周期、state等特性)
三个常用的Hook
- State hook:React() —— 使用状态
- Effect hook:React.useEffect() ——使用生命周期钩子
- Ref Hook:React.useRef() ——保存标签对象
State hook
- State hook让函数式组件也可以有state状态,并进行状态数据的读写操作
- 语法:cons [xxx,setxxx] = React.useState(initValue)
- useState()说明
参数:第一次初始化内部的值在内部做缓存
返回值:包含2个元素的数组,第1个为内部当前状态,第2个为更新状态值的函数 - setxxx有2种写法
setxxx(newValue),参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态
setxxx(value => newValue),参数为函数,接受原本的状态值,返回新的状态值,内部用其覆盖原来的状态
import React from 'react'
import { useState } from 'react'
export default function HooksDemo() {
//const [状态,更新状态的方法] = React.useState(初始值) useState的调用返回一个数组
const [count,setCount] = useState(0)
function handleAdd() {
//第一种写法
setCount(count+1)
//第二种写法
setCount(count => count+1)
}
return (
<div>
<h4>当前求和为{count}</h4>
<button onClick={handleAdd}>点我+1</button>
</div>
)
}
Effect hook
- Effect hook可以让你在函数组件中执行副作用操作(模拟类组件中的生命周期钩子)
- React中的副作用操作:发ajax请求数据、设置订阅/设置定时器、手动更改真实DOM
- 语法说明:
useEeffct(()=>{
//在次可以执行任何副作用操作
return ()=>{ //在组件卸载前执行
//在此做一些收尾工作,例如清除定时器/取消订阅
}
},[stateValue])//如果指定的是[ ],回调函数只会在第一次render()后执行 - 可以把useEeffct看成以下三个函数的组合
componentDidMount()、componentDidUpdate()、componentWillUnmount()
export default function HooksDemo() {
const [count,setCount] = useState(0)
useEffect(()=>{
let timer = setInterval(()=>{
setCount(count => count+1)
},1000)
return () => {
clearInterval(timer)
}
},[])
function unmount () {
ReactDOM.unmountComponentAtNode(document.getElementById('root'))
}
return (
<div>
<h4>当前求和为{count}</h4>
<button onClick={unmount}>卸载组件</button>
</div>
)
}
Ref Hook
- Ref Hook可以在函数组件中存储/查找组件内的标签或任意其他数据
- 语法:const RefContainer = useRef()
- 作用:保存标签对象,功能与React.createRef()一样
export default function HooksDemo() {
const myRef = useRef()
function handleShow () {
alert(myRef.current.value)
}
return (
<div>
<input type="text" ref={myRef}/>
<button onClick={handleShow}>点我提示数据</button>
</div>
)
}
useRoutes()
根据路由表,动态创建<Routes>和<Route>
//路由表配置 src/Routes/index.jsx
import { Navigate } from 'react-router-dom';
import Home from '../pages/Home'
import About from '../pages/About'
import Message from '../pages/Message'
import News from '../pages/News'
export default [
{
path: '/about',
element: <About/>
},
{
path: '/home',
element: <Home/>,
children:[
{
path: 'news',
element: <News/>
},
{
path: 'message',
element: <Message/>
}
]
},
{
path: '/',
element: <Navigate to="/home" replace={false}/>
}
]
// app.jsx
import './App.css';
import { Navigate, NavLink, useRoutes } from 'react-router-dom';
import routes from './Routes/index'
function App() {
const element = useRoutes(routes)
return (
<div>
<NavLink to="/about">About</NavLink>
<NavLink to="/home">Home</NavLink>
{element}
</div>
);
}
export default App;
useNavigate()
返回一个函数来实现变成导航
import React from 'react'
import { useNavigate } from 'react-router-dom'
export default function Demo() {
const navigate = useNavigate();
function showDetail () {
navigate('detail',{
replace: false,
state: {title:'111',content:'222'}
})
}
return (
<div><button onClick={showDetail}>查看详情</button></div>
)
}
useParams()、useSearchParams()、useLocation()、useMatch()
useParams():匹配当前路由的params参数,类似于5.x中的mach.params
useSearchParams():用于读取和修改当前位置的URL的查询字符串
import React from 'react'
import { useSearchParams } from 'react-router-dom'
export default function Detail() {
const [search,setSearch] = useSearchParams();
console.log(search)
const title = search.get('title');
const content = search.get('content');
return (
<div>
<button onClick={()=>setSearch('title=hh&content=hhh')}>点我更新</button>
标题:{title},内容:{content}
</div>
)
}
useLocation():获取当前location信息,对标5.x中路由组件的location属性
useMatch():返回当前匹配信息,对标5.x中路由组件的match属性