React 用一个简单案例体验一遍 React-dom React-router React-redux 全家桶

一、准备工作

本文略长,建议耐心读完,每一节的内容与上一节的内容存在关联,最好跟着案例过一遍,加深记忆。

1.1 创建项目

  • 第一步,执行下面的命令来创建一个 React 项目。
npx create-react-app react-example
cd react-example
  • 第二步,安装依赖,运行项目
yarn install 或 npm install
yarn start 或 npm run start

1.2 项目结构

如图:
项目结构

1.3 初始化

src/index.js 的默认代码删掉,保留下面这部分。

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById("root"));
const App = () => {
  return <div>Hello</div>
}
root.render(<App />);

现在项目看起来就像这样,一个简单的 Hello
请添加图片描述

二、React 的基本用法

如果你还不熟悉 React 的基础语法,可以阅读我前面写的 React & 工作日常语法。

1.1 输出 Hello, world

第一步肯定是要先来句 Hello,world!

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';

const root = ReactDOM.createRoot(document.getElementById("root"));
const App = () => {
  return <div>Hello, world!</div> // 改动点
}
root.render(<App />);

请添加图片描述

1.2 组件的使用

组件可以由函数或者类来进行创建,像上面的 App 函数就是一个组件,里面可以混合写 HTML & JS 代码,React 会自动帮我们解析这些语法,像这种写法就叫就 JSX

下面我将以函数的方式来定义组件作为案例,类组件在讲生命周期时做演示。

  • 第一步,随便定义一个叫 List 的组件,内容随便写,比如 Hi List
const List = () => {
  return <div>Hi List.</div>
}
  • 第二步,引入 List,目前入口只有 App,很明显只能放这里。
const App = () => {
  return <div>Hello, world! </List> </div>
}

效果:
请添加图片描述

1.3 组件嵌套组件

App 组件嵌套 List 组件,我们管这叫父子组件,App 是父组件, List 是子组件,当 List 套上 Item 组件时,那 Item 的父组件就是 List,而祖父组件是 App, 以此类推。

现在我们来给 List 嵌套一个 Item 组件。

const List = () => {
  // 多行时要用 () 包裹
  return (
    <ul>
      <Item/> // 引入
    </ul>
  )
}
const Item = () => {
  return <li>item1</li>
}

效果:
请添加图片描述

别忘了还可以写 JSX 的,现在试试用 Array.map 循环多个 Item 组件。

const List = () => {
  return (
    <ul>
      {[1, 2, 3, 4].map((num) => Item(num) )}
    </ul>
  )
}
const Item = (num) => {
  return <li key={num}>item{num}</li>
}

在看效果前思考下,上面代码具体会发生哪些变化?

  1. Item 函数组件多了个 num 参数,我们用它来接受,并用 {num} 括号包括起来进行访问
  2. <Item/> 的调用方式变成 Item(num) ,因为我们要将 num 值传递给 Item 函数,所以我们又发现了一个特性,在不传参的情况下直接声明 <Item/> 是会自动触发函数的。
  3. 循环组件时,key 属性得带上且是唯一的。

效果:
请添加图片描述

1.3 组件绑定点击事件

干巴巴的列表,没有交互行为怎么能行呢,
现在我们就来定义一个事件,当点击某个 Item 时提示对应的 num 数值,代码如下:

const onClickItem = (num) => {
  alert(num);
}
const Item = (num) => {
  return <li key={num} onClick={() => onClickItem(num)}>item{num}</li>
}

解释:

  1. 点击事件用 onClick 驼峰形式来表示,其它事件也是类似的,比如 onFocus, onMouse 等。
  2. onClick={() => 函数} 花括号返回一个箭头函数,函数里面就是返回我们定义的函数,后面点击时会触发。

不用怀疑语法是否有问题,连 JSX 语法都有了,你还在乎这个?

效果:
请添加图片描述

1.5 响应式数据

光弹窗没啥用啊,要不点击后直接变更 Item 的数据如何?
问题是… 怎么变更?直接将 num = xxx?熟悉 JS 的朋友应该知道,当 num 参数传递的是【基本类型】时只是一个副本,更改后对原来的 num 是无效的。
就算有效,你又如何将视图中的 num 也发生变化呢? 看来还是得借助 React 提供的语法了。
唉没办法,学吧~

  • 第一步,先将原来的 [1,2,3,4]useState 提供的函数来定义并导出 arr 变量数组,如图:
    请添加图片描述
    效果还是与原来一样,这里就不贴图了。

  • 第二步,在 arr 后面再声明一个 setArr 函数,名字随便定义,但一般用 set 开头作为规范好点,表示用来变更 arr 数据的。

const List = () => {
  const [arr, setArr] = useState([1, 2, 3, 4])
// ...省略
  • 第三步,触发 setArr 函数,更改 arr 数组里的数据来达到我们想要的视图变更效果
    请添加图片描述
    由于 setArr 是在 List 函数组件里定义的,其它函数无法直接访问,得通过传参的方式带过去、一直传到 onClickItem 中,有点绕,将就一下吧,相信你不介意的(/逃)。

这里我们重点关注这一段代码:

setArr(state => {
  const arr = [...state];
  arr[1] = 1000;
  return arr;
})

当点击后,将 arr[1] 改为 1000,并将新的 arr 返回出去,效果如图:
请添加图片描述
你可能注意到,state 就是原先的 arr,然后我们用扩展符号将它拷贝一份到新的 arr 中,为什么要这样做呢?直接 state[1] = 1000 再 return 出去不行吗,多此一举嘛这不是。

是可以这样做,数据也会发生变化了,但视图不会发生变化,因为 React 明确规定:state 是不可变数据,你不能直接改变它,而是要用一份副本去改变

为什么 state 要坚持不可变原则呢?官方也说了,当你要实现一个撤销&恢复的功能时就没辙了,或者说实现起来更复杂?React 这时要是还允许你去那岂不是有点不地道了,这不跟吃了上顿不考虑下顿的道理嘛。

小结:

  1. useState 可以声明响应式数据。
  2. state 数据不可变,要用副本代替,遵循不可变原则。

1.6 什么是钩子函数 Hook Function

其实我们已经用过钩子函数了,上面的 useState 就是一个钩子函数,React 内置了许多的钩子,比如 useEffect, useRef 等,这里就不一一介绍,只需明白以 use 为开头的均属于钩子函数即可。

我们也可以自定义钩子,问题来了,在什么样的场景下需要呢?里面写啥呢?
这个其实没有唯一答案,每个人对理解钩子的程度是不同的,导致有千千万万种类型的钩子

我个人更喜欢将它归为处理脏活的一类函数,更通俗点来说,是用来处理响应式数据的,比如,有个奖品业务的功能模块,针对这个模块,可能有验证奖品配置的逻辑,那么我就会给这个奖品加上几个 hook 函数,以便后续方便调用。

const usePrize = () => {
	const verifyPrizeConfig = (state) => {
		// Do something ...
	}
	const resetPrizeConfig = (state) => {
		// Do something ...
	}
	return [
		verifyPrizeConfig,
		resetPrizeConfig,
	]
}
const [ verifyPrizeConfig ] = usePrize();

1.7 组件的生命周期

每个组件渲染时,React 会逐步按顺序触发一些内置函数,这些被称为”生命周期函数“,我们可以根据不同周期函数来做一些业务处理,比如我想在组件渲染前先请求接口得到数据。

这里需要注意,函数组件是没有命周期函数的,只有类组件才有,既然这样,我们将 App 这个组件变成类组件即可,其它保持不变,谁规定类组件里面就不能嵌套函数组件

  • 第一步,将 App 函数组件改为类组件,如下:
// 源 App 函数组件
// const App = () => {
//   return <div>Hello, world! <List/> </div>
// }
// 新 APP 类组件
class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <div>Hello, world! <List /> </div>
  }
}
  • 第二步,添加生命周期函数,这里用最常见的 componentDidMount 函数,表示组件第一次渲染时提前触发。
class App extends React.Component {
  // 省略
  componentDidMount() {
    // Do something...
    alert('Init')
  }
}

请添加图片描述

1.8 函数组件模拟生命周期

你可能想,这不公平,函数组件凭啥没有周期函数?别急,React 提供的钩子函数 useEffect 就派上用场了,该钩子完全可以模拟生命周期的三大核心函数:

componentDidMount() {} 组件第一次渲染时,就刚刚用到的
componentDidUpdate() {} 组件数据更新时(state 更新)
componentWillUnMount() {} 组件销毁时

使用方式也很简单,这里以 List 组件作为案例,不能忘记我们的老伙伴~

  • 第一步,模拟 componentDidMount,如下:
import { useState, useEffect } from 'react';
const List = () => {
  const [arr, setArr] = useState([1, 2, 3, 4]);
  // 模拟 componentDidMount
  useEffect(() => {
    alert('List init') 
  });
  return (
    <ul>
      {arr.map((num) => Item(num, setArr) )}
    </ul>
  )
}

请添加图片描述

  • 第二步,模拟 componentDidUpdate,在 useEffect 的第二个参数监听 state:
// ... 省略
const [arr, setArr] = useState([1, 2, 3, 4])
 useEffect(() => {
    alert('List init')
  }, [arr]) // componentDidUpdate

当点击更新数据时,这个函数就会再次触发,如图:
请添加图片描述
请添加图片描述

  • 第三步,模拟 componentWillUnMount,在 useEffect 里面 return 一个函数即可。
const [arr, setArr] = useState([1, 2, 3, 4])
 useEffect(() => {
    alert('List init')
    return () => { // componentWillUnMount
      alert('List destroyed!');
    };
  }, [arr])

componentWillUnMount 什么时候触发呢?实际上,每当 state 更新时,组件会重新渲染一次,这属于销毁行为,因此当点击更新数据后,会先触发 componentWillUnMount ,再触发 componentDidUpdate 。
效果:

请添加图片描述
请添加图片描述
请添加图片描述

三、React-router-dom

1.1 什么是 React-router-dom

一个页面怎么够用呢,现在我们想要通过点击 item 进入另一个页面,且保持页面不刷新,这里便可以用 React 提供的插件 React-router-dom ,俗称路由来实现。

1.2 React-router-dom 和 React-router 版本的区别

React-router-dom 是基于 React-router 改造的新版本,现在大家常用的版本是 React-router-dom
本案例将用 React-router-dom 来作为演示。

1.3 React-router-dom 的使用

  • 第一步,下载 react-router-dom。
yarn add react-router-dom
  • 第二步,在 src/index.js 中引入。
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";
  • 第三步,将我们之前的 App 组件引入方式重新改造一下
// 旧代码
// root.render(<App />);
// 新代码
const router = createBrowserRouter([
  {
    path: "/",
    element: <App/>,
  },
]);

root.render(<RouterProvider router={router} />);

现在效果和原来没区别,这里解释下步骤:

  1. 将原来 root.render 里的 App 替换成 RouterProvider 组件
  2. createBrowserRoute 里面的 element 引入 App。
  3. path (路由),当访问 / 根目录时才会渲染 App 组件。
  • 第四步,新建 AppDetail 组件并挂载到 /detail 路由上。
const AppDetail = () => {
	return <h1>Detail data</h1>
}
const router = createBrowserRouter([
  {
    path: "/",
    element: <App/>,
  },
  // 挂载到 /detail 路由
  {
    path: "/detail",
    element: <AppDetail/>,
  },
]);
  • 第五步,访问 /detail 看看效果
    请添加图片描述
  • 第六步,以点击跳转的方式访问 /detail,这里用到 router 提供的 <Link> 标签。
import {
  createBrowserRouter,
  RouterProvider,
  Link,
} from "react-router-dom";
const Item = (num, setArr) => {
  return (
    <li key={num} onClick={() => onClickItem(num, setArr)}>
      <Link to='/detail'>item{num}</Link>
    </li>
  )
}

效果:
请添加图片描述

react-router-dom 就这么简单,至于其它 API 的使用可以参考文档,这里不过多讲解。

四、React-redux

1.1 什么是 React-redux

React-redux 可以用来管理全局状态 state 的工具,使得组件之间可以访问同一份 state。

1.2 什么时候用 React-redux

当多个组件重复使用同一份 state 时就可以考虑用 redux 将它提升到全局中,以便于维护。

1.3 React-redux 下载&配置

  • 第一步,下载 react-redux,这里官方还提供了一个工具包 @reduxjs/toolkit,里面包含了 react-redux 所有功能以及内置一些其它功能,是官方极力推荐的,这两个一起下载。
yarn add react-redux @reduxjs/toolkit
  • 第二步,在 src 下新建 store/index.js 文件,负责管理全局 state,初始化内容如下:
// ./src/store/index.js
import { configureStore, createSlice } from '@reduxjs/toolkit'
const userSlice = createSlice({
  name: 'User', // name 必填的,当前作用域的标识符,可以理解为 nameSpace 命名空间,否则页面上无法正常展示。
  initialState: { // 声明 state 的地方
  },
  reducers: { // 声明 reducer 函数的地方
  }
});
// 将 store 导出去。
const store = configureStore({
  reducer: userSlice.reducer
})

export default store;

  • 第三步,在 src/index.js 中引入 store
import store from './store/index';
import { Provider } from 'react-redux'
root.render(
  <Provider store={store}>
    <RouterProvider router={router} />
  </Provider>
);

解释:

  1. 从 store.js 中引入 store 对象。
  2. 从 redux 中引入 Provider 组件,并将原先的 RouterProvider 组件包裹起来。
  3. store 作为参数传递给 Provider 组件。

目前来讲,页面跟原来没有区别,但是现在我们多了 redux 的功能,何乐而不为呢。

1.4 什么是 Reducer

Reducer 与 Vuex 中的 mutations 差不多同一个意思,里面专门定义一些处理 state 的函数,reducer 主要接受一个 state 和一个 action ,根据这两个参数处理相关逻辑,然后返回新的 state (遵循前面所说的“不可变原则”)。

1.5 什么是 dispatch(action)

  • dispatch 是用来调用 reducer 函数的。
  • action 是 dispatch 调用 reducer 函数时要传递的一个描述对象,好让 reducer 知道该干什么事。该描述对象总共就俩参数:type/payload,type 是调用 reducer 的函数名,payload 是我们要传参的数据,给 reducer 接受用的。

1.6 使用

理解 reducer/dispatch/action 三大核心概念之后,我们来开始使用:

  • 第一步,在 initialState 对象中定义全局响应式数据。
// 省略...
initialState: {
	// 新增
    user: {
      name: 'Jack',
      desc: 'Hello,world!'
    }
},
  • 第二步,新建 User 组件,该组件用来访问上面声明的响应式数据,并挂载到 App 和 AppDetail 中渲染,代码如下:
// ./src/index.js
// ...省略
import { Provider, useSelector } from 'react-redux'
// 新增
const User = () => {
  // 用 redux 提供的钩子来获取 state
  const user = useSelector(state => state.user); 
  return (
    <div>
      <span>{user.name}</span>
      <span> says: {user.desc}</span>
    </div>
  )
}
// ./src/index.js
// ...省略
class App extends React.Component {
  // ...省略
  render() {
    return (
      <div>
        <User /> // 新增:挂载 User
        <List /> 
      </div>
    )
  }
}
const AppDetail = () => {
  return (
    <h1>
      Detail data
      <User /> // 新增:挂载 User
    </h1>
  )
}

现在的效果:Jack says: Hello,world!
请添加图片描述

  • 第三步,声明 reducer 函数来变更 state 数据。
// .src/store/index.js
// ...省略
reducers: { // 声明 reducer 函数的地方
	// 新增
    changeUserInfo(state, action) {
      const { payload } = action;
      switch(payload.state) {
        case 'name':
          return {
            ...state,
            user: {
              ...state.user,
              name: '杰克',
            }
          }
        case 'desc':
          return {
            ...state,
            user: {
              ...state.user,
              desc: '你好,世界!',
            }
          }
        default:
          return state;
      }
    }
  }

changeUserInfo 函数解释:

  1. 根据 payload.state 即我们准备传参的数据来变更用户名 name 还是描述
    desc
  2. 遵循不破坏 state 原则,这里我们用扩展符来合并。
  • 第四步,使用 dispatch(action) 来触发 reducer,完成变更效果。
// ./src/index.js
import { Provider, useSelector, useDispatch } from 'react-redux'
const User = () => {
  const user = useSelector(state => state.user);
  const dispatch = useDispatch(); // 引入触发 reducer 的钩子
  return (
    <div>
      <span>{user.name}</span>
      <span> says: {user.desc}</span>
      // 以下是新增的
      <button onClick={() => dispatch({
        type: 'User/changeUserInfo',
        payload: {
          state: 'name'
        }
      })}>
        更换名字
      </button>
      <button onClick={() => dispatch({
        type: 'User/changeUserInfo',
        payload: {
          state: 'desc'
        }
      })}>
        更换描述
      </button>
    </div>
  )
}

现在来看看总体效果:
请添加图片描述

五、总结

不知不觉,我们已经用到了 React-dom & React-router& React-redux:

root.render( // react-dom
  <Provider store={store}> // react-redux
    <RouterProvider router={router} /> // react-router-dom
  </Provider>
);

恭喜你已成功入门 React 全家桶,剩下就交给实践的时间来帮助我们熟能生巧。

有问题欢迎指出!

完!


案例已放在 github 上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/1227.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Springboot集成Swagger

一、Swagger简介注意点&#xff01; 在正式发布的时候要关闭swagger&#xff08;出于安全考虑&#xff0c;而且节省内存空间&#xff09;之前开发的时候&#xff0c;前端只用管理静态页面&#xff0c; http请求到后端&#xff0c; 模板引擎JSP&#xff0c;故后端是主力如今是前…

【宝塔面板部署nodeJs项目】网易云nodeJs部署在云服务器上,保姆级教程,写网易云接口用自己的接口不受制于人

看了很多部署的&#xff0c;要么少步骤&#xff0c;要么就是写的太简洁&#xff0c;对新手不友好 文章目录前言一、下载网易云nodejs项目1. git clone下载&#xff0c;两种方式2. 运行项目二、使用步骤1. 先在本地运行2.测试接口三、部署服务器1. 在宝塔面板安装pm2管理器2. 压…

字符函数和字符串函数【上篇】

文章目录&#x1f396;️1.函数介绍&#x1f4ec;1.1. strlen&#x1f4ec;1.2. strcpy&#x1f4ec;1.3. strcat&#x1f4ec;1.4. strcmp&#x1f4ec;1.5. strncpy&#x1f4ec;1.6. strncat&#x1f4ec;1.7. strncmp&#x1f396;️1.函数介绍 &#x1f4ec;1.1. strlen …

入行 5年,跳槽 3次,我终于摸透了软件测试这行(来自过来人的忠告)

目录 前言 第一年 第二年 第三年 第四年 作为过来人的一些忠告 前言 最近几年行业在如火如荼的发展壮大&#xff0c;以及其他传统公司都需要大批量的软件测试人员&#xff0c;但是20年的疫情导致大规模裁员&#xff0c;让人觉得行业寒冬已来&#xff0c;软件测试人员的职…

【YOLOv8/YOLOv7/YOLOv5/YOLOv4/Faster-rcnn系列算法改进NO.60】损失函数改进为wiou

前言作为当前先进的深度学习目标检测算法YOLOv8&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列文章&#xff0c;将重点对YOLOv8的如何改进进行详细的介绍&…

css属性学习

css属性 就是我们选择器里面 { } 中的内容 字体样式 font-size 控制字体大小&#xff1a;单位px&#xff08;像素&#xff09; 默认字体占16个像素 <p style"font-size:30px;">font-size&#xff1a;字体大小&#xff0c;单位的话可以用px表示占的像素个数&…

Mini-Xml 经典实例Demo

欢迎小伙伴的点评✨✨&#xff0c;相互学习、博主将自己研发xml微型服务器的经验与之分享&#x1f30f;&#x1f30f;&#x1f642; 文章目录前言一、使用mxml库编写Xml文件1.1 经典实例Demo_11.2、经典实例Demo_21.3、经典实例Demo_3二、总结前言 本章将会给大家带来mini-xml…

在我的MacBook上捣鼓ESP8266

周三是我们的篮球日&#xff0c;打篮球后总是会有些兴奋&#xff0c;然后就容易睡不着&#xff0c;额&#xff0c;睡不着就拿我的ESP8266开发板出来捣鼓一下。先下载编译工具链https://github.com/espressif/ESP8266_RTOS_SDK下载sdkgit clone https://github.com/espressif/ES…

C++程序在内存中的模型

进程&#xff08;Process&#xff09;是计算机中的程序&#xff0c;数据集合在其上运行的一次活动&#xff0c;是系统进行资源分配的基本单位。每个进程都有自己独立的虚拟内存地址空间&#xff0c;这个虚拟的内存地址空间一般是线性连续的&#xff0c;这个内存地址空间是虚拟的…

面试官想看我写一篇关于“原型链”和“构造函数”深入理解的文章

前言&#xff1a; 在参加工作的面试过程中&#xff0c;我搬出了我的个人掘金账号写在了简历里&#xff0c;面试官很感兴趣&#xff0c;他不仅关注了我的账号&#xff0c;还想让我写一篇《原型链》的见解&#xff0c;由于老早就想总结一篇关于原型的文章&#xff0c;奈何自己刚开…

07平衡负载:gRPC是如何进行负载均衡的?

负载均衡(Load Balance),其含义就是指将请求负载进行平衡、分摊到多个负载单元上进行运行,从而协同完成工作任务。 负载均衡的主要作用: 提升并发性能:负载均衡通过算法尽可能均匀的分配集群中各节点的工作量,以此提高集群的整体的吞吐量。 提供可伸缩性:可添加或减少服…

Springboot新手开发 Cloud篇

前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏&#xff1a;后端专栏 &#x1f4e7;如果文章知识点有错误的地方&#xff0c;…

汇编语言与微机原理(1)基础知识

前言&#xff08;1&#xff09;本人使用的是王爽老师的汇编语言第四版和学校发的微机原理教材配合学习。&#xff08;2&#xff09;推荐视频教程通俗易懂的汇编语言&#xff08;王爽老师的书&#xff09;&#xff1b;贺老师C站账号网址&#xff1b;&#xff08;3&#xff09;文…

在visual studio 2022 C++中配置最新版OpenCV和可能错误解决方案

前面我们写了一篇博文有关在C#中配置OpenCV&#xff0c;但C#版本的OpenCV的学习资源相对较少&#xff0c;C版的和Python版的比较多。这里先说说C版的如何配置吧&#xff01;总共完成四步即可使用起来。 文章目录一、下载并安装OpenCV1、下载OpenCV2、安装OpenCV二、配置环境1、…

【python】喜欢XJJ?这不得来一波大采集?

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 俗话说的好&#xff1a;技能学了~就要用在自己喜欢得东西上&#xff01;&#xff01; 这我不得听个话~我喜欢小姐姐&#xff0c;跳舞的小姐姐 这不得用python把小姐姐舞采集下来~嘿嘿嘿 完整源码、素材皆可点击文章下方名片…

条款20:当std::shared_ptr可能悬空时使用std::weak_ptr

自相矛盾的是&#xff0c;如果有一个像std::shared_ptr&#xff08;见条款19&#xff09;的但是不参与资源所有权共享的指针是很方便的。换句话说&#xff0c;是一个类似std::shared_ptr但不影响对象引用计数的指针。这种类型的智能指针必须要解决一个std::shared_ptr不存在的问…

Mysql 竟然还有这么多不为人知的查询优化技巧,还不看看?

前言 Mysql 我随手造200W条数据&#xff0c;给你们讲讲分页优化 MySql 索引失效、回表解析 今天再聊聊一些我想分享的查询优化相关点。 正文 准备模拟数据。 首先是一张 test_orde 表&#xff1a; CREATE TABLE test_order (id INT(11) NOT NULL AUTO_INCREMENT,p_sn VARCHA…

Spring事务和事务传播机制

目录 Spring中事务的实现 1、通过代码的方式手动实现事务 2、通过注解的方式实现声明式事务 2.1、Transactional作用范围 2.2、Transactional参数说明 2.3、注意事项 2.4、Transactional工作原理 事务隔离级别 1、事务特性 2、Spring中设置事务隔离级别 2.1、MySQL事…

Linux:函数指针做函数参数

#include <stdio.h> #include <stdlib.h> //创建带有函数指针做参数的函数框架api //调用者要先实现回调函数 //调用者再去调用函数框架 //所谓的回调是指 调用者去调用一个带有函数指针做参数的函数框架&#xff0c;函数框架反过来要调用调用者提供的回调函数 …

蓝桥杯冲击-02约数篇(必考)

文章目录 前言 一、约数是什么 二、三大模板 1、试除法求约数个数 2、求约数个数 3、求约数之和 三、真题演练 前言 约数和质数一样在蓝桥杯考试中是在数论中考察频率较高的一种&#xff0c;在省赛考察的时候往往就是模板题&#xff0c;难度大一点会结合其他知识点考察&#x…