湘潭网站建设 很好磐石网络网店关键词怎么优化
REACT-路由v6
- 1. App.js
- 2. 搭建路由
- 2.1 普通写法
- 2.2 使用useRoutes构建路由
- 2.3 重定向封装
- 2.4 嵌套路由中的组件Outlet
- 3. 导航跳转
- 3.2 声明式导航(NavLink标签)
- 3.2 编程式导航跳转(useNavigate)
- 3.2.1 获取参数
- 3.2.1.1 useSearchParams
- 3.2.1.1 useParams
- 4. Login.js
- 5. 自定义封装withRouter
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.childrenconst 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.childrenconst 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 axiosfrom '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={()=>{// 不能单独修改单个parmassetSearchParmas({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)