irpas技术客

【REACT-路由v6】_历目

irpas 4129

REACT-路由v6 1. App.js2. 搭建路由2.1 普通写法2.2 使用useRoutes构建路由2.3 重定向封装2.4 嵌套路由中的组件Outlet 3. 导航跳转3.2 声明式导航(NavLink标签)3.2 编程式导航跳转(useNavigate)3.2.1 获取参数3.2.1.1 useSearchParams3.2.1.1 useParams 4. Login.js5. 自定义封装withRouter 2021年11月 react router 6 成为默认版本,npm安装时自动安装6版本 npm i react-router-dom

1. App.js import './App.css'; import { HashRouter } from 'react-router-dom';//路由模式BrowserRouter import IndexRouter from './router/IndexRouter'; import Tabbar from './components/Tabbar/Tabbar'; function App() { return ( <div className="App"> <li>dddd</li> <HashRouter> <IndexRouter></IndexRouter> <Tabbar></Tabbar> </HashRouter> </div> ); } export default App; 2. 搭建路由

src/router/IndexRouter.js

2.1 普通写法 import React, { lazy, Suspense } from 'react' import {Routes,Route,Navigate} from 'react-router-dom' import Redirect from '../components/Redirect' export default function IndexRouter() { return ( <Routes> {/* index等同于他的父级地址,这里等同于http://localhost:3000/ */} {/* <Route index element={<Films/>} /> */} <Route path='/films' element={LazyLoad('Films')}> <Route index element={<Navigate to="/films/nowPlaying" />} /> {/* 嵌套路由需要在组件Films中配套Outlet(出口)一起使用 */} <Route path='nowPlaying' element={LazyLoad('films/NowPlaying')} /> <Route path='/films/commingSoon' element={LazyLoad('films/CommingSoon')} /> </Route> <Route path='/cinemas' element={LazyLoad('Cinemas')} /> <Route path='/login' element={LazyLoad('Login')} /> <Route path='/center' element={<AuthCom>{LazyLoad('Center')}</AuthCom>} /> {/* <Route path='/detail' element={LazyLoad('DetailsSearch)} /> */} <Route path='/detail/:id/:type' element={LazyLoad('DetailsParams')} /> {/* 重定向-Navigate:星号可以匹配任意地址*/} {/* <Route path="/" element={<Navigate to="/films" />}/> */} <Route path="/" element={<Redirect to="/films" />}/> <Route path="*" element={LazyLoad('NotFound')}/> </Routes> ) } //路由拦截 function AuthCom({children}){//props.children const isLogin = window.localStorage.getItem('token'); return isLogin?children:<Redirect to="/login"/> } //路由懒加载,重定向的不用再调用懒加载函数 const LazyLoad = path => { const Comp = lazy(()=>import('../views/'+path)); return ( <Suspense fallback={<>加载中。。。</>}> <Comp/> </Suspense> ) } 2.2 使用useRoutes构建路由 import React, { lazy, Suspense } from 'react' import {Routes,Route,Navigate, useRoutes} from 'react-router-dom' import Redirect from '../components/Redirect' export default function IndexRouter() { const element = useRoutes([ { path:'/films', element:LazyLoad('Films'), children:[ { path:'', element:<Navigate to="/films/nowPlaying" /> }, { path:'nowPlaying', element:LazyLoad('films/NowPlaying') }, { path:'/films/commingSoon', element:LazyLoad('films/CommingSoon') }, ] }, { path:'/cinemas', element:LazyLoad('Cinemas') }, { path:'/login', element:LazyLoad('Login') }, { path:'/center', element:<AuthCom>{LazyLoad('Center')}</AuthCom> }, { path:'/detail/:id/:type', element:LazyLoad('DetailsParams') }, { path:'/', element:<Redirect to="/films" /> }, { path:'*', element:LazyLoad('NotFound') }, ]); return ( element ) } //路由拦截 function AuthCom({children}){//props.children const isLogin = window.localStorage.getItem('token'); return isLogin?children:<Redirect to="/login"/> } //路由懒加载,重定向的不用再调用懒加载函数 const LazyLoad = path => { const Comp = lazy(()=>import('../views/'+path)); return ( <Suspense fallback={<>加载中。。。</>}> <Comp/> </Suspense> ) } 2.3 重定向封装

src/components/Redirect.js

import React, { useEffect } from 'react' import {useNavigate} from 'react-router-dom' export default function Redirect({to}) { const Navigate = useNavigate(); useEffect(()=>{ Navigate(to,{replace:true}); },[]); return null; }; 2.4 嵌套路由中的组件Outlet

src/views/Films.js

import React from 'react' import {Outlet} from 'react-router-dom' export default function Films() { return ( <div> <div style={{height:"200px",background:"pink"}}>轮播</div> {/* 这里会呈现 NowPlaying或commingSoon的内容 */} <Outlet></Outlet> </div> ) } 3. 导航跳转 3.2 声明式导航(NavLink标签)

src/components/Tabbar/Tabbar.js

import style from './Tabbar.module.css' import React from 'react' import {NavLink} from 'react-router-dom' export default function Tabbar() { return ( <div> <ul> <li> {/* Link没有高亮className*/} {/* <Link to="/films">影院</Link> */} <NavLink to="/films" className={({isActive})=>isActive?style.tabActive:''}>电影</NavLink> </li> <li> <NavLink to="/cinemas" className={({isActive})=>isActive?style.tabActive:''}>影院</NavLink> </li> <li> <NavLink to="/center" className={({isActive})=>isActive?style.tabActive:''}>我的</NavLink> </li> </ul> </div> ) }

src/components/Tabbar/Tabbar.module.css

.tabActive{ color: pink; } /* 会影响全局,最好加自定义className */ li{ list-style: none; } 3.2 编程式导航跳转(useNavigate)

src/views/films/NowPlaying.js

import React,{useState,useEffect} from 'react' import axios from 'axios'; import { useNavigate } from 'react-router-dom'; import FilmItem from '../../components/FilmItem'; export default function NowPlaying() { const [list,setList] = useState([]); useEffect(()=>{ //异步获取数据 axios({ url:"https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=9261499", method:'get', headers:{ 'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16745641013679850669801473","bc":"110100"}', 'X-Host': 'mall.film-ticket.film.list' } }).then(res=>{ setList(res.data.data.films) }) },[]) // const navigate = useNavigate(); // const handleChangePage = id => { // //query-url传参 // // navigate(`/detail?id=${id}&type=2`) // //路由传参 // navigate(`/detail/${id}/type=2`) // } return ( <div> { list.map(item=>{ return ( // <div key={item.filmId} onClick={() => handleChangePage(item.filmId)}>{item.name}</div> <FilmItem key={item.filmId} {...item} /> ) }) } </div> ) } 3.2.1 获取参数 3.2.1.1 useSearchParams

src/views/Details-searchParams.js

navigate(`/detail?id=${id}&type=2`) import React from 'react' import { useSearchParams } from 'react-router-dom' export default function Details() { const [searchParmas,setSearchParmas] = useSearchParams(); console.log(searchParmas.get('id'))//获取参数 console.log(searchParmas.has('name'))//判断是否有参数 return ( <div> Details <button onClick={()=>{ // 不能单独修改单个parmas setSearchParmas({id:1000,type:1})//修改参数 }}>猜你喜欢</button> </div> ) } 3.2.1.1 useParams

src/views/Details-params.js

import React from 'react' import { useNavigate, useParams } from 'react-router-dom' export default function Details() { const params = useParams(); const navigate = useNavigate(); console.log(params.id)//获取参数 return ( <div> Details <button onClick={()=>{ navigate('/detail/1000/3') }}>猜你喜欢</button> </div> ) } 4. Login.js import React from 'react' import { useNavigate } from 'react-router-dom'; export default function Login() { const navigate = useNavigate(); return ( <div> <h1>登录页面</h1> <input type="text" /> <button onClick={()=>{ localStorage.setItem('token',"xxx"); navigate('/center') }}>登录</button> </div> ) } 5. 自定义封装withRouter import React from 'react' import { useLocation, useNavigate, useParams } from 'react-router-dom' export default function withRouter(Component) { return function(props){ const navigate = useNavigate(); const params = useParams(); const location = useLocation(); return <Component {...props} history={{navigate,params,location}}/> } } import React from 'react' import withRouter from './withRouter' function FilmItem(props) { const handleChangePage = id => { props.history.navigate(`/detail/${id}/type=2`)//跳转页面 console.log(props.history.params)//获取参数对象 console.log(props.history.location)//获取当前路由 } return ( <div> <li onClick={() => handleChangePage(props.filmId)}>{props.name}</li> </div> ) } export default withRouter(FilmItem)


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #REACT路由v6