react-router-dom(v5)
基本路由使用
import {HashRouter,Route} from 'react-router-dom'
function App() {
return (
<HashRouter>
<Route path="/films" component={Films}></Route>
<Route path="/cinemas"component={Cinemas} ></Route>
<Route path="/center" component={Center}></Route>
<Route path="/Home" render={()=>{return <Home></Home>}}></Route>
</HashRouter>
);
}
export default App;
function Films(){
return <div>Films</div>
}
function Cinemas(){
return <div>Cinemas</div>
}
function Center(){
return <div>Center</div>
}
function Home(){
return <div>Home</div>
}
Route中path属性是请求路径,component是匹配路径需要渲染的组件。
路由重定向
import {HashRouter,Route,Redirect} from 'react-router-dom'
function App() {
return (
<HashRouter>
<Route path="/films" component={Films}></Route>
<Route path="/cinemas"component={Cinemas} ></Route>
<Route path="/center" component={Center}></Route>
<Redirect from ='/' to="/films"></Redirect>
</HashRouter>
);
}
Redirect组件是重定向组件,当路由匹配from,会将路由重定向到to所代表的路由。
Switch(只渲染第一个匹配的路由)
import {HashRouter,Route,Redirect,Switch} from 'react-router-dom'
function App() {
return (
<HashRouter>
<Switch>
<Route path="/films" component={Films}></Route>
<Route path="/cinemas"component={Cinemas} ></Route>
<Route path="/center" component={Center}></Route>
<Redirect from ='' to="/films"></Redirect>
</Switch>
</HashRouter>
);
}
exact(精确路由匹配)
<Route exact path="/cinemas"component={Cinemas} ></Route>
路由没有被exact标识的时候,可以匹配很多路径 如/cinemas/a,/cinemas/b/c,但是使用exact标识的时候只能被路由器/cinemas匹配,这就是精确匹配的作用。
路由匹配可能会匹配多个路由,而最终只会渲染最后一个组件,如果路由被Switch包裹,则会渲染第一个可匹配的组件,后续路由不再进行匹配。
嵌套路由
import {HashRouter,Route,Switch} from 'react-router-dom'
function App() {
return (
<HashRouter>
<Route path="/films" component={Films}></Route>
</HashRouter>
);
}
export default App;
function Films(){
return <div>
<Switch>
<Route path="/films/person" component={Person}></Route>
<Route path="/films/dog" component={Dog}></Route>
<Route path="/films/cat" component={Cat}></Route>
</Switch>
</div>
}
function Person(){
return <div>Person</div>
}
function Dog(){
return <div>Dog</div>
}
function Cat(){
return <div>Cat</div>
}
Films是一级路由匹配的组件, 一级路由组件内可以定义二级路由,从而使二级路由的组件可以渲染在一级路由组件内。
路由导航
1,声明式导航
import {NavLink} from 'react-router-dom'
<NavLink to='/films'>电影</NavLink>
<NavLink to='/cinemas'>影院</NavLink>
<NavLink to='/center'>个人中心</NavLink>
NavLink是一个路由链接,当点击的时候会去匹配具体的路由
注意,NavLink只能包含在router组件内使用
2,编程式导航(props.history)
props.history.push('/films')
被Route路由包裹的组件内的props拥有history,location等参数。
3,编程式导航(hook useHistory跳转)
import {useHistory} from 'react-router-dom'
const history = useHistory();
history.push('/films')
路由传参
1,声明式导航传参 动态路由定义:
<Route path="/films/:id" component={Films}></Route>
组件接收路由参数:
props.match.params.id
2,编程式动态路由获取参数
props.history.push({
pathname:'/films',query:{day:"friday}
})
获取参数:
props.location.query.day;
3,编程式动态路由获取参数
props.history.push({
pathname:'/films',state:{day:"friday}
})
获取参数
props.match.state.day;
路由模式
react-router-dom默认路由模式是hash模式,这种请求路径会带有一个#,改变为browser模式如下:
import {BrowserRouter,Route} from 'react-router-dom'
function App() {
return (
<BrowserRouter>
<Route path="/films" component={Films}></Route>
<Route path="/cinemas"component={Cinemas} ></Route>
<Route path="/center" component={Center}></Route>
</BrowserRouter>
);
}
注意,Browser模式会真正的向后台发起请求,当请求页面不存在的时候,可能会报错,解决方法,后台需要进行处理,重新渲染前端页面
withRouter
import {withRouter} from 'react-router-dom'
withRouter(MyComponent)
MyComponent组件一旦被withRouter包裹,无论MyComponent组件是不是路由组件,都能够在内部porps中获取对应的history等路由信息。
react-router-dom(v6)
基本使用:
import {HashRouter as Router,Route,Routes,Link} from 'react-router-dom'
function App() {
return (
<Router>
<Link to="/person">人类</Link>
<Link to="/dog">狗</Link>
<Link to="/cat">猫</Link>
<Routes>
<Route path="/person" element ={<Person/>}></Route>
<Route path="/dog" element ={<Dog/>}></Route>
<Route path="/cat" element ={<Cat/>}></Route>
</Routes>
</Router>
);
}
export default App;
function Person(){
return <div>Person</div>
}
function Dog(){
return <div>Dog</div>
}
function Cat(){
return <div>Cat</div>
}
- 与版本5不同的一点是,v6版本的Route必须用Routes包裹,v6中的Routes代替了v5版本的switch.
- v5的路由组件使用component和render属性引入,然而v6使用element属性
嵌套路由
一级路由:
<Route path="/person" element ={<Person/>}>
<Route path="women" element ={<Women/>}></Route>
<Route path="man" element ={<Man/>}></Route>
</Route>
Person组件:
function Person(){
return (
<div>
person
<Outlet></Outlet>
</div>
)
}
v5版本的嵌套路由是将嵌套的路由写在组件内部,v6中的使嵌套路由更简单,Outlet是子路由组件的一个占位,此组件的匹配的子路由组件会显示在<Outlet></Outlet>位置上。
路由index作用
<Route path="/person" index element ={<Person/>}></Route>
近匹配父路由时,会显示当前组件。 index匹配当前
路由重定向
Navigate组件进行路由导航
<Route path="/dog" element ={<Navigate to="/o/>}></Route>
也可以使用useNavigate hook自定义重定向路由组件:
export default function Redirect(props){
const navigate = useNavigate();
useEffect(()=>{
navigate(props.to,{replace:true});
},[])
return;
}
v6中移除了v5的重定向组件
路由导航
1,声明式导航
1:Link
<Link to="/person">人类</Link>
<Link to="/dog">狗</Link>
<Link to="/cat">猫</Link>
2:NavLink
<NavLink to="person" className ={({isActive}) => isActive ? 'myclassName' : ''}> </NavLink>
v6移除了的activeClassName 和 activeStyle,而是使用className获取isActive来处理高亮显示效果。v6新增了组件也可做导航组件。
2,编程式导航
import {useNavigate} from 'react-router-dom';
const to = useNavigate();
to('/list',{state:data});
v5使用useHistory进行跳转,v6使用useNavigate代替了v5的useHistory。
获取路由参数
1,路由穿参:
路由定义
<Route path="/person/:id" element ={<Person/>}></Route>
路由参数获取(通过useParams获取):
import {useParams} from 'react-router-dom';
function Person(){
const params = useParams();
return <div>{params.id}</div>
}
2:query穿参:
路由定义:
const navigate = useNavigate();
navigate('/preson?id=1');
获取参数(通过useSearchParams获取):
import {useSearchParams} from 'react-router-dom';
function Person(){
const [searchParams,setSearchParams] = useSearchParams();
return <div>{searchParams.get("id")}</div>
}
withRouter的替代
v6中删除了withRouter,而是使用useNavigate代替其功能的实现。如果是类组件,可以自己使用useNavigate封装成一个withRouter组件,从而在类组件中使用类似withRouter的功能。
useLocation
这个hook可以获取对应的路由信息。v5中的location中的信息是在history中获取的。
路由懒加载
懒加载组件封装:
const lazyLoad = (path) => {
const Comp = React.lazy(()=>import('/${path}'));
return (
<React.Suspense fallback = {<>加载中。。。</>}>
<Comp />
</React.Suspense>
)
}
路由中使用
<Route path="man" element ={lazyLoad('Person')}></Route>
useRoutes
v6中的useRoutes代替react-router-config
const routes = useRoutes([
{
path:'/person',
element: <Person/>,
children:[
{
path:'/women',
element: <Women/>,
},
{
path:'/man',
element: <Man/>,
}
]
},
{
path:'/cat',
element: <Cat/>,
},
{
path:'/dog',
element: <Dog/>
}
])