【React 进阶】掌握 React18 全部 Hooks

一、数据更新驱动

1. useState

1. 基础介绍

useState主要用于声明和操作状态变量,可以使函数组件像类组件一样拥有state

const [state, setState] = useState(initialState);

state:状态,作为渲染视图的数据源

setState:改变state的函数。可以直接传递新状态,也可以传递一个根据先前状态来计算新状态的函数(函数式更新)

initialState:初始化值。如果是函数,则将函数的返回值作为初始值

2. 直接传递新状态

点击按钮,count变为1

import { useState } from "react";function App() {const [count, setCount] = useState(0);return (<div>{count}<buttononClick={() => {setCount(1);}}>按鈕</button></div>);
}export default App;

3. 函数式更新

根据先前的state更新state。将按钮中的setCount调用方式改为:

setCount((prev) => prev + 1);

4. 使用场景:使用key重置状态

会有这么一种业务场景:在一系列筛选或输入后面,增加重置按钮

如果是受控组件,我们可以将值置空。如果是非受控组件,我们可以使用key重置组件的状态

import { useState } from "react";export default function App() {const [version, setVersion] = useState(0);const handleReset = () => {setVersion(version + 1);};return (<><button onClick={handleReset}>重置</button><Form key={version} /></>);
}const Form = () => {const hanlderSubmit = (e: React.FormEvent<HTMLFormElement>) => {e.preventDefault();console.log(e.target);};return (<><form onSubmit={hanlderSubmit}><input type="text" name="user" /><input type="password" name="password" /><button type="submit">提交</button></form></>);
};

5. 注意事项

(1)set函数是异步的,调用set函数后,不能立即获取最新的值

const handleClick = () => {setCount(count + 1); //setCount(0+1)console.log(count); //0
};

(2)获取的是渲染时候的值

即使2s后打印,但当时读取count的时候,count值为0,因此打印出来的结果也为0。可以理解为渲染快照

const handleClick = () => {setCount(count + 1); //setCount(0+1)setTimeout(() => {console.log(count); // 还是 0!}, 2000);
};

如果要获取最新的值,可以使用useRef

import { useRef} from "react";export default function App() {const countRef = useRef(0)const handleClick = () => {countRef.current += 1setTimeout(() => {console.log( countRef.current); // 1}, 2000);};return (<><button onClick={handleClick}>按钮</button></>);
}

(3)如果新值与当前state相同(由Object.is比较确定),将跳过重新渲染

点击按钮,因为对象info的引用地址还是指向同一个,因此不会再重新渲染

import { useState } from "react";export default function App() {const [info, setInfo] = useState({name: "张三",age: 20,});const handleClick = () => {setInfo(Object.assign(info, { age: info.age + 1 }));};console.log("渲染");return (<>{info.name}--{info.age}<button onClick={handleClick}>按钮</button></>);
}

要想触发渲染,需传递一个新对象:

setInfo(Object.assign({}, info, { age: info.age + 1 }));
//或使用扩展运算符
setInfo({ ...info, age: info.age + 1 });

(4)setState 自动批量处理

React 18 之前,setState 只在合成事件与钩子函数中自动批量处理,在promise、setTimeout或js原生事件中,都不会进行批处理

React 18中,默认所有的更新都将自动批量处理

import { useState } from "react";export default function App() {const [count, setCount] = useState(0);const handleClick = () => {setTimeout(() => {setCount(1);setCount(2);setCount(3);setCount(2);});};console.log("渲染");return (<>{count}<button onClick={handleClick}>按钮</button></>);
}

点击按钮,组件只会更新一次,并且值为最后一次调用set传入的值2

2. useReducer

1. 基础介绍

useReducer 是 react-hooks 提供的能够在无状态组件中运行类似redux功能的api

const [state,dispatch] = useReducer(reducer,initialState,init?);

state:状态state

dispatch:改变state的函数

reducer:与 redux 中的 reducer相同,一个函数,接收state与action,并返回一个新的state

initialState:初始值

init:将init函数作为useReducer的第三个参数传入,这样初始state将被设置为init(initialState)

2. 使用场景:状态管理

import { useReducer } from "react";const initialCount = {count: 0,
};type InitialCount = typeof initialCount;type ACTIONTYPE =| { type: "increment" }| { type: "decrement" }| { type: "reset"; payload: InitialCount };/* 对初始值进行处理 */
function init(initialCount: InitialCount) {/* 如果传入的count初始值小于0,则置为0 */if (initialCount.count < 0) {return { count: 0 };} else {return initialCount;}
}function reducer(state: InitialCount, action: ACTIONTYPE) {switch (action.type) {case "increment":return { count: state.count + 1 };case "decrement":return { count: state.count - 1 };case "reset":return init(action.payload || initialCount);default:throw new Error();}
}const App = () => {const [state, dispatch] = useReducer(reducer, initialCount, init);return (<>Count: {state.count}<buttononClick={() => dispatch({ type: "reset", payload: initialCount })}>Reset</button><button onClick={() => dispatch({ type: "decrement" })}>-</button><button onClick={() => dispatch({ type: "increment" })}>+</button></>);
};export default App;

useReducer 与 Context 配合使用,可以形成一个小范围的状态管理功能

3. useSyncExternalStore

1. 基础介绍

useSyncExternalStore 可以在外部数据源变化时,自动更新视图。一般是第三方状态管理库使用。

const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)

subscribe:订阅 store 的变化

getSnapshot:返回 store 当前值

getServerSnapshot:用于服务端渲染

2. 使用场景:订阅浏览器 API

订阅外部数据源,当外部数据源更新时,自动更新视图

import { useSyncExternalStore } from "react";export default function ChatIndicator() {//监听浏览器网络连接状态  const isOnline = useSyncExternalStore(subscribe, () => navigator.onLine);return <h1>{isOnline ? "Online" : "Disconnected"}</h1>;
}function subscribe(callback:any) {window.addEventListener("online", callback);window.addEventListener("offline", callback);return () => {window.removeEventListener("online", callback);window.removeEventListener("offline", callback);};
}

4. useTransition

useTransition 是一个帮助你在不阻塞 UI 的情况下更新状态的 React Hook

1. 基础介绍

const [ isPending , startTransition ] = useTransition ()

isPending :布尔值,表示是否正在等待;

startTransition:接收一个的函数,可以把里面的更新任务变成过渡任务

2. 使用场景:将状态更新标记为低优先级,先执行其他高优先级任务

页面会先显示list2的内容,之后再显示list1的内容

import { useState, useEffect, useTransition } from "react";const App = () => {const [list1, setList1] = useState<null[]>([]);const [list2, setList2] = useState<null[]>([]);const [isPending, startTransition] = useTransition();useEffect(() => {startTransition(() => {//将状态更新标记为 transition  setList1(new Array(10000).fill(null));});}, []);useEffect(()=>{setList2(new Array(10000).fill(null));},[])return (<>{isPending ? "pending" : "nopending"}{list1.map((_, i) => (<div key={i}>{i}</div>))}-----------------list2{list2.map((_, i) => (<div key={i}>6666</div>))}</>);
};export default App;

5. useDeferredValue

1. 基础介绍

可以让我们延迟渲染不紧急的部分,类似于防抖但没有固定的延迟时间

const deferrredValue = useDeferredValue(value)

value:想延迟的值

deferrredValue:延迟值。只有当前没有紧急更新任务时,才会更新为最新值,否则返回旧值

2. useDeferredValue 和 useTransition 的区别

相同点:useDeferredValue 本质上和内部实现与 useTransition 一样都是标记成了过渡更新任务

不同点:useTransition是处理了一段逻辑,useDeferredValue是生产一个新的状态

3. 使用场景:受控输入框与长列表

将 input 更新作为紧急的部分优先处理,长列表更新作为不紧急的部分延迟处理。

import { useState, useDeferredValue, memo } from "react";export default function App() {const [value, setValue] = useState("");const deferredValue = useDeferredValue(value);const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {setValue(e.target.value);};return (<div><input value={value} onChange={handleChange} /><LongList deferredValue={deferredValue} /></div>);
}const LongList = memo(({ deferredValue }: { deferredValue: string }) => {return (<div className="container"><div className="list">{Array(10000).fill(null).map((_,i) => (<div key={i}>{deferredValue}</div>))}</div></div>);
});

注意点:

如果直接在父组件中展示1万个长列表节点,value更新,触发组件渲染,会去处理长列表节点,导致卡顿。

将长列表拆分成子组件,延迟的值传递给子组件,并使用memo包裹,这样只要等deferredValue的值更新,才会重新处理长列表的节点

二、生命周期

1. useEffect

1. 基础介绍

useEffect实现了 componentDidMount、componentDidUpdate 和 componentWillUnmount 三个API的功能

useEffect(fn, deps?)

fn:回调函数,会在初始化或依赖项变化时运行

deps:依赖项,是一个数组

2. 实现componentDidMount

第二个参数传空数组,只会在初始化时触发一次

useEffect(() => {//请求接口数据}, []);

3. 实现componentDidUpdate

在第二个参数传入依赖状态,当依赖状态改变时会重新渲染

useEffect(() => {//请求接口数据}, [props.name]);

内部是浅比较,源码中用for循环配合Object.is实现

4. 实现componentWillUnmount

return一个回调函数,用来清除副作用

import { useCallback, useEffect, useState } from "react";const App = () => {const [position, setPosition] = useState({ x: 0, y: 0 });const handleMouse = useCallback((e: MouseEvent) => {setPosition({x: e.pageX,y: e.pageY,});}, []);useEffect(() => {window.addEventListener("mousemove", handleMouse);return () => {//取消监听  window.removeEventListener("mousemove", handleMouse);};}, [handleMouse]);return (<div>x:{position.x} y:{position.y}</div>);
};export default App;

2. useLayoutEffect

1. 基础介绍

在浏览器layout之后,painting之前执行。回调函数中执行的代码可能会堵塞浏览器绘制。常用来在绘制之前获取DOM节点信息,修改DOM结构,这样浏览器只用绘制一次

useLayoutEffect(setup, deps?)

fn:回调函数,会在初始化或依赖项变化时运行

deps:依赖项

2. 使用场景:在浏览器绘制之前获取DOM节点信息

import { useState, useRef, useLayoutEffect } from "react";function App() {const ref = useRef<HTMLDivElement>(null);const [tooltipHeight, setTooltipHeight] = useState(0);useLayoutEffect(() => {const { height } = ref.current?.getBoundingClientRect() || { height: 0 };setTooltipHeight(height);}, []);return (<div ref={ref} style={{ height: 300 }}>容器的高:{tooltipHeight}</div>);
}export default App;

3. useInsertionEffect

1. 基础介绍

useInsertionEffect是一个专为CSS-in-JS 库的开发者打造的钩子,在DOM更新之前执行(比useLayoutEffect早)

useInsertionEffect(setup, deps?)

n:回调函数,会在初始化或依赖项变化时运行

deps:依赖项

2. 使用场景:提前注入style标签

import { useInsertionEffect } from "react";function App() {useInsertionEffect(() => {/* 动态创建 style 标签插入到 head 中 */const style = document.createElement("style");style.innerHTML = `.css-in-js{color: red;font-size: 20px;}`;document.head.appendChild(style);}, []);return <div className="css-in-js"> useInsertionEffect </div>;
}export default App;

三、状态保存

1. useMemo

1. 基础介绍

在每次重新渲染的时候能够缓存计算的结果

const cachedValue = useMemo(calculateValue, deps)

calculateValue:一个函数,函数的返回值作为缓存值

deps:一个数组,存放当前 useMemo 的依赖项。依赖项改变时,会运行calculateValue重新计算

cachedValue:返回值,如果 deps 中有依赖项改变,返回重新执行 calculateValue 产生的值,否则取上一次缓存值

2. 使用场景

(1)缓存计算结果

import { useState, useMemo } from "react";function App() {const [count, setCount] = useState(0);const memoizedValue = useMemo(() => {//创建1000位数组const list = new Array(1000).fill(null).map((_, i) => i);//对数组求和const total = list.reduce((res, cur) => (res += cur), 0);//返回计算的结果return count + total;//添加依赖项,只有count改变时,才会重新计算}, [count]);return (<div>{memoizedValue}<button onClick={() => setCount((prev) => prev + 1)}>按钮</button></div>);
}export default App;

(2)缓存渲染列表

import { useState, useMemo } from "react";function App() {const [list] = useState(["张三", "李四"]);const renderList = useMemo(() => (<div>{list.map((i, v) => (<span key={v}>{i}</span>))}</div>),[list]);return (<div>{renderList}</div>);
}export default App;

3. React.memo与useMemo的区别

React.memo:对外部传值props进行浅比较,避免不必要的重复渲染,相当于shouldComponentUpdate;

useMemo:对组件内部状态state进行浅比较,避免不必要的重复渲染

2. useCallback

1. 基础介绍

缓存函数的引用地址,仅在依赖项改变时才会更新

const cachedFn = useCallback(fn, deps)

fn:想要缓存的函数

deps:是否更新 fn 的所有响应式值的一个列表

2. 使用场景:避免子组件重复渲染

默认情况下,当一个组件重新渲染时, React 将递归渲染它的所有子组件。我们通常对于有props的子组件会使用React.memo进行包裹

import { useState, memo } from "react";const App = () => {const [count, setCount] = useState(0);const handleClick = () => {setCount((prev) => prev + 1);};return (<div>{count}<MyButton handleClick={handleClick} /></div>);
};interface Props {handleClick: () => void;
}const MyButton = memo(({ handleClick }: Props) => {console.log("子组件渲染");return <button onClick={handleClick}>按钮</button>;
});export default App;

点击按钮,可以发现即使子组件使用memo包裹了,但还是更新了,控制台打印出“子组件渲染”。这是因为父组件App每次更新时,函数handleClick每次都返回了新的引用地址,因此对于子组件来说每次传入的都是不一样的值,从而触发重渲染。

使用useCallback可以缓存函数的引用地址,将handleClick改为

const handleClick = useCallback(()=>{setCount(prev=>prev+1)
},[])

再点击按钮,会发现子组件不会再重新渲染

3. useMemo与useCallback的区别

useMemo常用来缓存计算结果,useCallback常用来缓存函数的引用地址

useMemo如果返回一个函数,同样能够做到缓存函数的引用地址,与useCallback等效

四、状态获取与传递

1. useContext

1. 基础介绍

向上查找最近的使用context Provider 提供的 value 值

const value = useContext(SomeContext)

SomeContext:由React.createContext创建的context

value:获取使用 Provider 提供的 value 值

2. 使用场景:向组件树深层传递数据

import {useState,useCallback,createContext,useMemo,useContext,
} from "react";const defaultValue = { count: 0, handleClick: () => {} };/* 1. 创建Context */
const MyContext = createContext(defaultValue);const App = () => {const [count, setCount] = useState(0);const handleClick = useCallback(() => {setCount((prev) => prev + 1);}, []);//传递值和改变该值的方法给子组件const contextValue = useMemo(() => ({count,handleClick,}),[count, handleClick]);return (/* 2. 提供Context值 */<MyContext.Provider value={contextValue}><MyButton /></MyContext.Provider>);
};const MyButton = () => {/* 3. 获取Context值 */const { count, handleClick } = useContext(MyContext);return (<div>{count}<button onClick={handleClick}>按钮</button></div>);
};export default App;

2. useRef

1. 基础介绍

用来创建一个不需要渲染的值

const ref = useRef(initialValue)

initialValue:ref 对象的 current 属性的初始值。

ref:一个只有一个属性current的对象,在后续的渲染中,useRef 将返回同一个对象

2. 可以用来访问dom节点或子组件

import { useEffect, useRef } from "react";function App() {const domRef = useRef(null);useEffect(() => {console.log(domRef.current);}, []);return <div ref={domRef}>dom</div>;
}export default App;

3. 值的更改不会触发视图更新

import { useRef, useState } from "react";function App() {const countRef = useRef(0);const [count, setCount] = useState(0);console.log('组件渲染');return (<div>{countRef.current}{count}<buttononClick={() => {countRef.current += 1;}}>ref+1</button><button onClick={() => setCount((prev) => prev + 1)}>state+1</button></div>);
}export default App;

点击ref+1按钮,countRef值增加,但视图不会更新。点击state+1按钮,视图更新,组件重新渲染,打印出countRef最新的值 

4. 返回的引用,在组件更新时不会被改变(返回同一个对象),可以用来清除定时器

import { useEffect, useRef } from "react";function App() {const timeRef = useRef<NodeJS.Timer>();useEffect(() => {timeRef.current = setInterval(() => {console.log("1");}, 1000);//在组件卸载时,清除定时器,防止内存泄漏return () => {clearInterval(timeRef.current);};}, []);return <div></div>;
}export default App;

3. useImperativeHandle

1. 基础介绍

与forwardRef配合,自定义暴露给父组件的实例值或函数

useImperativeHandle(ref, createHandle, [deps])

ref:接受forwardRef传递过来的ref

createHandle:处理函数,返回值作为暴露给父组件的ref对象

deps:依赖项deps,依赖项更改形成新的ref对象

2. 使用场景:组件通信中,父组件调用子组件

import { forwardRef, useRef, useImperativeHandle } from "react";/* 定义ref类型 */
interface ForwardObject {focus: () => void;
}function App() {const ref = useRef<ForwardObject>(null);return (<div><MyInput ref={ref} /><button onClick={() => ref.current?.focus()}>使输入框获取焦点</button></div>);
}/* 子组件 */
const MyInput = forwardRef((props, ref) => {const inputRef = useRef<HTMLInputElement>(null);useImperativeHandle(ref,() => ({focus: () => {inputRef.current?.focus();},}),[]);return <input ref={inputRef} />;
});export default App;

五、工具类

1. useDebugValue

1. 基础介绍

在 React 开发工具 中为自定义 Hook 添加标签

useDebugValue(value, format?)

value:在 React 开发工具中显示的值

format:一个格式化函数,将接收 value 作为参数,并返回格式化后的显示值

2. 使用场景:在 React 开发工具中为自定义 Hook 添加标签

import { useDebugValue, useState } from "react";const App = () => {useNetworkStatus();return <div></div>;
};function useNetworkStatus() {const [isOnline] = useState(false);// 在开发者工具中的这个 Hook 旁边显示标签// NetworkStatus:"Offline"useDebugValue(isOnline ? "Online" : "Offline");return isOnline;
}export default App;

2. useID

1. 基础介绍

生成唯一 ID。解决了在服务器渲染中,服务端和客户端产生 id 不一致的问题

const id = useId()

2. 使用场景:为属性生成唯一 ID

import { useId } from "react";export default function Form() {const id = useId();return (<div><label htmlFor={id}>chose</label><input type="checkbox" id={id} name="chose" /></div>);
}

点击chose,能够看到复选框被选中

提示:不要使用 useId 来生成列表中的 key,key 应该由你的数据生成

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

菜鸟驿站二维码/一维码 取件识别功能

特别注意需要引入 库文 ZXing 可跳转&#xff1a; 记录【WinForm】C#学习使用ZXing.Net生成条码过程_c# zxing-CSDN博客 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Net.…

2024年亚太地区数学建模大赛D题-探索量子加速人工智能的前沿领域

量子计算在解决复杂问题和处理大规模数据集方面具有巨大的潜力&#xff0c;远远超过了经典计算机的能力。当与人工智能&#xff08;AI&#xff09;集成时&#xff0c;量子计算可以带来革命性的突破。它的并行处理能力能够在更短的时间内解决更复杂的问题&#xff0c;这对优化和…

教程 - 在 Creo Elements/Pro 中使用 Mechanica 分析杆的 von-mises 应力?

这是教程。 步骤1&#xff1a; 在“零件”模式下启动 Creo Elements/Pro。 步骤2&#xff1a; 草绘>>顶平面并绘制一个直径为 20mm 的圆。 步骤3&#xff1a; 将其挤出 200 毫米。 步骤4&#xff1a; 应用>>机械. 步骤5&#xff1a; 单击“确定”&…

ssm框架-spring-spring声明式事务

声明式事务概念 声明式事务是指使用注解或 XML 配置的方式来控制事务的提交和回滚。 开发者只需要添加配置即可&#xff0c; 具体事务的实现由第三方框架实现&#xff0c;避免我们直接进行事务操作&#xff01; 使用声明式事务可以将事务的控制和业务逻辑分离开来&#xff0c;提…

基于单片机的多功能跑步机控制系统

本设计基于单片机的一种多功能跑步机控制系统。该系统以STM32单片机为主控制器&#xff0c;由七个电路模块组成&#xff0c;分别是&#xff1a;单片机模块、电机控制模块、心率检测模块、音乐播放模块、液晶显示模块、语音控制模块、电源模块。其中&#xff0c;单片机模块是整个…

写给Vue2使用者的Vue3学习笔记

&#x1f64b;‍请注意&#xff0c;由于本人项目中引入了unplugin-auto-import的依赖&#xff0c;所以所有的代码示例中均未手动引入各种依赖库&#xff08;ref、reactive、useRouter等等&#xff09; 初始环境搭建 npm init vuelatest模板语法 插值 同 Vue2 <span>…

C# 数据结构之【图】C#图

1. 图的概念 图是一种重要的数据结构&#xff0c;用于表示节点&#xff08;顶点&#xff09;之间的关系。图由一组顶点和连接这些顶点的边组成。图可以是有向的&#xff08;边有方向&#xff09;或无向的&#xff08;边没有方向&#xff09;&#xff0c;可以是加权的&#xff…

短剧系统小程序开发产品设计实例解析

短剧系统小程序开发架构深度解析引言 随着数字娱乐市场的蓬勃发展&#xff0c;短剧因其紧凑的情节、创新的表现形式和便捷的观看体验&#xff0c;迅速吸引了大量观众的关注。作为承载短剧内容的重要平台&#xff0c;短剧系统小程序不仅需要在用户体验、内容管理等方面做到极致&…

AI数字人视频小程序:引领未来互动新潮流

当下&#xff0c;随着人工智能技术的不断创新发展&#xff0c;各类AI系统已经成为了创新市场发展的重要力量&#xff0c;AI文案、AI数字人、AI视频等&#xff0c;为大众带来更加便捷的创作方式&#xff0c;AI成为了一个全新的风口&#xff0c;各种AI红利持续释放&#xff0c;市…

解决vue-pdf的签章不显示问题

在使用vue-pdf 4.3.0时发现上传一般的普通pdf正常预览&#xff0c;但是上传带有红头文件的和和特殊字体的pdf无法正常内容显示&#xff0c;文字丢失问题。 1、查看控制台报错信息 2、缺少字体原因 getNumPages(url) {var loadingTask pdf.createLoadingTask({url: url,//引入…

跨境电商API接口:数据采集与业务集成的核心

跨境电商作为全球贸易的重要组成部分&#xff0c;正随着互联网技术的发展而迅速增长。在这个过程中&#xff0c;API接口扮演了至关重要的角色&#xff0c;它们不仅提高了运营效率&#xff0c;还增强了安全性和用户体验。本文将深入探讨跨境电商API接口的应用、重要性以及面临的…

【linux013】文件操作命令篇 - less 命令

文章目录 less 命令1、基本用法2、常见选项3、交互式键盘命令4、举例5、注意事项 less 命令 less 是 Linux 中强大的文件分页查看命令&#xff0c;比 more 更灵活且功能更强大。less 支持双向滚动、搜索、显示大文件等功能&#xff0c;适用于查看文件内容或管道输出的大量文本…

力扣 无重复字符的最长字串-3

无重复字符的最长字串-3 class Solution { public:// 解决方法&#xff1a;双指针int lengthOfLongestSubstring(string s) { // 如果字符串为空&#xff0c;直接返回0if (s.length() 0)return 0;// 如果字符串不为空&#xff0c;字符串每个字符都不同的情况下&#xff0c;最…

如何在Ubuntu当中利用CloudCompare软件进行点云配准拼接?

1.首先需要安装相应的cloudcompare软件&#xff0c;以下有两种方式&#xff1a;第一种直接在ubuntu的软件商店里搜索CloudCompare软件进行install&#xff0c;我这里已经安装完毕。 方式二&#xff1a;可以直接原码安装&#xff1a; github地址&#xff1a; https://github.co…

贴贴,一款windows剪切板管理软件

贴贴&#xff0c;一款windows剪切板管理软件 软件下载官网 https://tietieapp.com 软件界面 软件界面简洁、信息展示清晰。软件会自动记录你复制过的内容。包括哪个软件复制的、复制的时间。支持图片、文本、文件等多种格式。支持持久化&#xff0c;电脑重启记录仍然存在。支持…

RocketMQ的使⽤

初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种⽅式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要⻢上回复。 两种⽅式各有优劣&#xff0c;打电话可以⽴即得到响应&#xff0c;但…

初试无监督学习 - K均值聚类算法

文章目录 1. K均值聚类算法概述2. k均值聚类算法演示2.1 准备工作2.2 生成聚类用的样本数据集2.3 初始化KMeans模型对象&#xff0c;并指定类别数量2.4 用样本数据训练模型2.5 用训练好的模型生成预测结果2.6 输出预测结果2.7 可视化预测结果 3. 实战小结 1. K均值聚类算法概述…

JSON,事件绑定

文章目录 JSON事件绑定输入框input和div的内容返回获取dom元素数组还是单个对象for循环为什么要写const那一行&#xff0c;直接写 hobbys[index].checked true;可以吗const不是常量吗&#xff0c;为什么用const声明的element的属性值可以改变&#xff1f; 黑马学习笔记 JSON 定…

学习HTML第三十一天

学习文章目录 七. 普通按钮八. 文本域九.下拉框 七. 普通按钮 注意点&#xff1a;普通按钮的 type 值为 button &#xff0c;若不写 type 值是 submit 会引起表单的提交 八. 文本域 常用属性如下&#xff1a; rows 属性&#xff1a;指定默认显示的行数&#xff0c;会影响文…

基于Multisim的汽车尾灯控制电路设计与仿真

1、电路由四个按键控制&#xff0c;分别对应左转、右转、刹车和检查。 2、当左转或右转键按下时,左侧或右侧的 3个汽车尾灯按照左循环或右循环的顺!2/3 点亮&#xff0c;点亮时间为 1秒。 3、当刹车时&#xff0c;所有的尾灯同时闪烁&#xff0c;闪烁时间为1秒。 4、当检查时…