react的生命周期函数
1. react所有的生命周期函数
https://react.docschina.org/docs/react-component.html
挂载
当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:
更新
当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:
卸载
当组件从 DOM 中移除时会调用如下方法:
2. 常用的生命周期方法
创建阶段
constructor
作用: (1) 获取props (2) 初始化state
render
作用:渲染组件到页面中,无法获取页面中的DOM对象
componentDidMount()
(1) 组件已经挂载到页面中 (2) 可以进行DOM操作,比如:获取到组件内部的DOM对象 (3) 可以发送请求获取数据 (4) 可以通过 setState() 修改状态的值 注意:在这里修改状态会重新渲染
运行和交互阶段
componentDidUpdate(prevProps, prevState)
作用:组件已经被更新 参数:旧的属性和状态对象
卸载阶段
componentWillUnmount()
组件卸载期间,只有一个函数,这个函数也有一个显著的特点:组件一辈子只能执行一次 使用说明 只要组件不再被渲染到页面中,那么这个方法就会被调用( 渲染到页面中 -> 不再渲染到页面中 )
作用:在卸载组件的时候,执行清理工作,比如清除定时器
讲解用案例代码
子组件
// 子组件 class Child extends Component { //构造方法 constructor() { console.log('Child-constructor'); super() this.state = { parentMsg: '父组件的数据' } } // 组件挂载后 componentDidMount(){ console.log('Child-componentDidMount'); } // 是否应该更新组件 shouldComponentUpdate(){ console.log('Child-shouldComponentUpdate'); return true } // 组件更新后 componentDidUpdate(){ console.log('Child-componentDidUpdate'); } // 组件卸载前 componentWillUnmount(){ console.log('Child-componentWillUnmount'); } //组件渲染 render() { console.log('Child-render'); return ( <div> <p>子组件------------------{this.state.parentMsg}</p> </div> ); } }
父组件
// 父组件 class App extends Component { // 构造方法 constructor() { console.log('App-constructor'); super() this.state = { parentMsg: '父组件的数据' } } // 组件挂载后 componentDidMount(){ console.log('App-componentDidMount'); } // 是否应该更新组件 shouldComponentUpdate(){ console.log('App-shouldComponentUpdate'); return true } // 组件更新后 componentDidUpdate(){ console.log('App-componentDidUpdate'); } // 组件卸载前 componentWillUnmount(){ console.log('App-componentWillUnmount'); } change = ()=>{ this.setState({ parentMsg: '新的新的' }) } //组件渲染 render() { console.log('App-render'); return ( <div> <p>父组件-------------------{this.state.parentMsg}</p> <Child msg={this.state.parentMsg}></Child> <p><button onClick={this.change}>改变父组件的数据</button></p> </div> ); } }
react 路由v6使用
1. 安装路由依赖包
npm i react-router-dom -S
2. 案例代码
import React from 'react //引入路由中的各种API import { HashRouter, BrowserRouter, Routes, Route, Navigate, Link, NavLink, Outlet } from 'react-router-dom' // 引入路由相关组件 import Home from './Home' import Cart from './Cart' import My from './My' import NotFound from './NotFound' import FooterNav from './FooterNav' import Tv from './home/Tv' import Ai from './home/Ai' import Login from './Login' export default function App() { return ( <BrowserRouter> <Routes> <Route path="/home" element={<Home></Home>}> <Route path="tv" element={<Tv></Tv>}></Route> <Route path="ai" element={<Ai></Ai>}></Route> </Route> <Route path="/cart" element={<Cart></Cart>}></Route> <Route path="/login" element={<Login></Login>}></Route> <Route path="/my" element={<My></My>}></Route> <Route path="/" element={<Navigate to="/home"></Navigate>}></Route> <Route path="*" element={<NotFound></NotFound>}></Route> </Routes> <FooterNav></FooterNav> </BrowserRouter> ) }
3. 路由API
3.1 BrowserRouter和HashRouter
-
二者都是路由的包裹元素,设置路由模式
-
BrowserRouter是history模式, 生产版本需要后端进行相应的配置, 路径前没有'#',比较美观
-
HashRouter是hash模式,路由前有'#'
3.2 Routes
路由配置的包裹元素,<Route>必须放在<Routes>中,不然报错
3.3 Route
<Route path="/cart" element={<Cart></Cart>}></Route>
3.4 Navigate重定向
<Route path="/" element={<Navigate to="/home"></Navigate>}></Route>
3.5 Link和NavLink
<Link to="/movie" >电影</Link>
<NavLink to="/find" class="active">发现</NavLink>
4. 嵌套路由
4.1 定义嵌套路由
<Route path="/home" element={<Home></Home>}>
<Route path="tv" element={<Tv></Tv>}></Route>
<Route path="ai" element={<Ai></Ai>}></Route>
</Route>
4.2 默认路由
<Route path="/home" element={<Home></Home>}>
<Route index element={<Tv></Tv>}></Route>
<Route path="ai" element={<Ai></Ai>}></Route>
</Route>
4.3 Outlet定义二级路由出口
import React,{useState,useEffect} from 'react' import style from './Home.css' import { Outlet,NavLink,useNavigate} from 'react-router-dom' export default function Home() { return ( <div> <div className="header"> <p><NavLink to="" >电视</NavLink></p> <p><NavLink to="ai" >智能</NavLink></p> </div> <Outlet></Outlet> </div> ) }
5. 动态路由
5.1 动态路由
<Route path="/list/:id" element={<List></List>}></Route>
5.2 路由跳转
<p><NavLink to="/list/5">列表</NavLink></p>
5.3 获取动态路由参数
import { useParams } from 'react-router-dom'; ... const params = useParams() console.log(params.id) //5
6. React-router 的Hooks
import { useNavigate,useParams,useSearchParams,useLocation } from 'react-router-dom';
6.1 useNavigate
const navigate = useNavigate() //跳转到/my navigate("/my") //跳转到上一页 navigate(-1) //跳转到/my,并替换当前历史记录 navigate("/my",{replace: true}) //携带参数 navigate("/my",{replace: true,state:{arr:[1,2,3]}})
6.2 useParams
动态路由
<Route path="/list/:id" element={<List></List>}></Route>
<p><NavLink to="/list/5">列表</NavLink></p>
const params = useParams()
console.log(params.id) //5
6.3 useSearchParams
import { useSearchParams } from 'react-router-dom'; // 当前路径为 /foo?id=12 function Foo(){ const [searchParams] = useSearchParams(); console.log(searchParams.get('id')) // 12 return ( <div>foo</div> ) }
6.4 useLocation
-
hash: ""
-
key: "h8dnd0wk"
-
pathname: "/list/5"
-
search: ""
-
state: null
6.4 案例代码
import { useNavigate,useParams,useLocation } from 'react-router-dom'; ... export default function List() { //用navigate实现编程式导航 const navigate = useNavigate() //获取动态路由的参数 const params = useParams() //获取url信息 const location = useLocation() const toUrl = ()=>{ // navigate("/my") navigate("/my",{replace: true}) } return ( <div> list <hr /> <button onClick={toUrl}>回到我的</button> </div> ) }
7. 仿小米App的路由配置
7.1 FooterNav.css
.footerNav { display: flex; justify-content: space-around; position: absolute; width: 100%; height: 60px; left: 0; bottom: 0; background-color: #aaa; } .footerNav .active{ border: 1px solid #000; background-color: #f00; }
7.2 FooterNav.js
import React from 'react' import { Link, NavLink } from 'react-router-dom' import './FooterNav.css' export default function FooterNav() { return ( <div className="footerNav"> <p><NavLink to="/home">首页</NavLink></p> <p><NavLink to="/cart">购物车</NavLink></p> <p><NavLink to="/my">我的</NavLink></p> <p><NavLink to="/list/5">列表</NavLink></p> </div> ) }
7.3 App.js
import React from 'react' import { HashRouter,BrowserRouter,Routes, Route,Navigate,Link,NavLink,Outlet} from 'react-router-dom' import Home from './Home' import Cart from './Cart' import My from './My' import NotFound from './NotFound' import FooterNav from './FooterNav' import Tv from './home/Tv' import Ai from './home/Ai' import Login from './Login' import isLogin from './util/token' import List from './List' export default function App() { return ( <BrowserRouter> <Routes> <Route path="/home" element={<Home></Home>}> <Route path="tv" element={<Tv></Tv>}></Route> <Route path="ai" element={<Ai></Ai>}></Route> </Route> <Route path="/cart" element={isLogin() ?<Cart></Cart>:<Login></Login>}></Route> <Route path="/login" element={<Login></Login>}></Route> <Route path="/my" element={<My></My>}></Route> <Route path="/my" element={<My></My>}></Route> <Route path="/list" element={<List></List>}></Route> <Route path="/" element={<Navigate to="/home"></Navigate>}></Route> <Route path="*" element={<NotFound></NotFound>}></Route> </Routes> <FooterNav></FooterNav> </BrowserRouter> ) }
7.4 Home.css
.header { display: flex; justify-content: space-around; } .header .active { border: 1px solid #000; } .header .atdh { background-color: #f00; }
7.5 Home.js
import React,{useState,useEffect} from 'react' import style from './Home.css' import { Outlet,NavLink,useNavigate} from 'react-router-dom' export default function Home() { const navigate = useNavigate(); useEffect(()=>{ navigate('/home/tv') },[])// eslint-disable-line return ( <div> <div className="header"> <p><NavLink to="tv" >电视</NavLink></p> <p><NavLink to="ai" >智能</NavLink></p> </div> <Outlet></Outlet> </div> ) }
8. useRoutes的使用
<Route path="/home" element={<Home></Home>}> <Route path="tv" element={<Tv></Tv>}></Route> <Route path="ai" element={<Ai></Ai>}></Route> </Route>
在App.js中通过json数据实现路由配置
import React from 'react' import { BrowserRouter as Router, Navigate, useRoutes } from 'react-router-dom' import Home from './pages/Home' import Category from './pages/Category' import Phone from './pages/Category/Phone' import NoteBook from './pages/Category/NoteBook' import GoodsList from './pages/GoodsList' import My from './pages/My' import Detail from './pages/Detail' import NotFound from './pages/NotFound' const GetAllRoutes = () => { const routes = useRoutes([ { path: '/', element: <Navigate to="/Home" /> }, { path: '/Home', element: <Home /> }, { path: '/Category', element: <Category />, children: [ { //默认路由 index: true, element: <Phone /> }, { path: 'NoteBook', element: <NoteBook /> } ] }, { path: '/GoodsList', element: <GoodsList /> }, { path: '/My', element: <My /> }, { path: '/Detail/:id', element: <Detail /> }, { path: '/404', element: <NotFound /> }, { path: '*', element: <NotFound /> } ]) return routes; } export default function App() { return ( <Router> <GetAllRoutes /> </Router> ) }
9. 路由懒加载和鉴权
lazy()路由懒加载
import {lazy} from 'react'
const Later = lazy(() => import('./Later'));
Suspense组件
import { lazy, Suspense } from 'react'; const Later = lazy(() => import('./Later')); export default function App { return ( <div> <Suspense fallback={<div>loading...</div>}> <Later /> </Suspense> </div> ); }
案例涉及文件列表
src/routes/index.js
src/routes/config.js
src/routes/privateRoute.js
案例代码
src/routes/privateRoute.js
/** * PrivateRoute使用方式 * <PrivateRoute element={<Cart>} tag="权限"> </PrivateRoute> * props: {element:, tag: } */ import { Navigate } from "react-router-dom"; const PrivateRoute = props => { const isLogin = localStorage.getItem("token") return isLogin ? ( (props.element) ) : ( <Navigate to="/login"></Navigate> ); }; export default PrivateRoute;
src/routes/config.js
import PrivateRoute from './privateRoute'; import { Suspense } from 'react'; const WrapperRouteComponent = ({ titleId, auth, ...props }) => { if (titleId) { document.title = titleId } return ( <Suspense fallback={<div>loading...</div>}> {auth ? <PrivateRoute {...props} /> : (props.element)} </Suspense> ) }; export default WrapperRouteComponent;
src/routes/index.js
import { lazy } from 'react'; import Home from '../Home'; import WrapperRouteComponent from './config'; import { useRoutes, Navigate } from 'react-router-dom'; const NotFound = lazy(() => import(/* webpackChunkName: "404'"*/ '../NotFound')); const Ai = lazy(() => import(/* webpackChunkName: "ai'"*/ '../home/Ai')); const Tv = lazy(() => import(/* webpackChunkName: "tv'"*/ '../home/Tv')); const Cart = lazy(() => import(/* webpackChunkName: "Cart'"*/ '../Cart')); const My = lazy(() => import(/* webpackChunkName: "My'"*/ '../My')); const List = lazy(() => import(/* webpackChunkName: "List'"*/ '../List')); const Detail = lazy(() => import(/* webpackChunkName: "Detail'"*/ '../Detail')); const Login = lazy(() => import(/* webpackChunkName: "Login'"*/ '../Login')); const routeList = [ { path: '/', element: <Navigate to="/home" /> }, { path: '/home', // element: <Home />, element: <WrapperRouteComponent element={<Home />} titleId="首页" />, children: [ { path: 'ai', element: <WrapperRouteComponent element={<Ai />} titleId="ai" />, }, { path: 'tv', element: <WrapperRouteComponent element={<Tv />} titleId="tv" />, } ] }, { path: '/cart', element: <WrapperRouteComponent element={<Cart />} titleId="Cart" auth={true}/>, }, { path: '/my', element: <WrapperRouteComponent element={<My />} titleId="My" /> }, { path: '/list', element: <WrapperRouteComponent element={<List />} titleId="List" /> }, { path: '/detail/:id/:type', element: <WrapperRouteComponent element={<Detail />} titleId="Detail" /> }, { path: '/login', element: <WrapperRouteComponent element={<Login />} titleId="Login" /> }, { path: '/404', element: <NotFound /> }, { path: '*', element: <NotFound /> } ] const RenderRouter = () => { const element = useRoutes(routeList); return element; }; export default RenderRouter;
App.js
import React from 'react' import "./App.css" //引入路由中的各种API import { BrowserRouter as Router, } from 'react-router-dom' import RenderRouter from './routes' import TabBar from './TabBar' export default function App() { return ( <div className="app"> <Router> <RenderRouter></RenderRouter> <TabBar></TabBar> </Router> </div> ) }
标签:生命,const,周期函数,element,react,组件,import,路由 From: https://www.cnblogs.com/liu521125/p/18083899