• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
liu521125
记录自己的学习之路
博客园    首页    新随笔    联系   管理    订阅  订阅

react的生命周期函数

react的生命周期函数

1. react所有的生命周期函数

https://react.docschina.org/docs/react-component.html

挂载

当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

  • constructor()

  • static getDerivedStateFromProps()

  • render()

  • componentDidMount()

更新

当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

  • static getDerivedStateFromProps()

  • shouldComponentUpdate()

  • render()

  • getSnapshotBeforeUpdate()

  • componentDidUpdate()

卸载

当组件从 DOM 中移除时会调用如下方法:

  • componentWillUnmount()

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

  1. hash: ""

  2. key: "h8dnd0wk"

  3. pathname: "/list/5"

  4. search: ""

  5. 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>
  )
}

 

 

本文来自博客园,作者:刘先生的爱心博客,转载请注明原文链接:https://www.cnblogs.com/liu521125/p/18083899

一点一滴记录着学习html5 css3 和js 的时光
posted @ 2024-03-19 20:31  刘先生的爱心博客  阅读(278)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3