【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 应该由你的数据生成
相关文章:

【React 进阶】掌握 React18 全部 Hooks
一、数据更新驱动 1. useState 1. 基础介绍 useState主要用于声明和操作状态变量,可以使函数组件像类组件一样拥有state const [state, setState] useState(initialState);state:状态,作为渲染视图的数据源 setState:改变st…...

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter) 更新以gitee为准: 文章目录 数据预测概念和适用方式线性系统的适用性 数据预测算法和卡尔曼滤波公式推导状态空间方程和观测器先验估计后验估计…...

【SQL50】day 2
目录 1.每位经理的下属员工数量 2.员工的直属部门 3.判断三角形 4.上级经理已离职的公司员工 5.换座位 6.电影评分 7.修复表中的名字 8.患某种疾病的患者 9.删除重复的电子邮箱 1.每位经理的下属员工数量 # Write your MySQL query statement below #e1是经理,…...

【内存管理】理解 `WeakReference` 以更好地管理 Android 应用中的内存
在 Android 应用开发中,内存管理至关重要。糟糕的内存管理可能导致“内存泄漏”,即一些不再需要的对象仍然留在内存中,最终导致性能下降,甚至应用崩溃。WeakReference 就是帮助解决这个问题的一种工具。在本文中,我们将…...

解决IDEA中Maven管理界面不是层级结构的问题
文章目录 0. 前言1. 点击Maven管理界面右上角的三个点2. 勾选将模块分组3. 分组后的层级结构 更多 IDEA 的使用技巧可查看 IDEA 专栏中的文章:IDEA 0. 前言 在 IDEA 中,如果项目中有很多子模块,每个子模块中又有一个或多个子模块时…...

Linux运维篇-iscsi存储搭建
目录 概念实验介绍环境准备存储端软件安装使用targetcli来管理iSCSI共享存储 客户端软件安装连接存储 概念 iSCSI是一种在Internet协议上,特别是以太网上进行数据块传输的标准,它是一种基于IP Storage理论的存储技术,该技术是将存储行业广泛…...

深度学习基础练习:代码复现transformer重难点
2024/11/10-2024/11/18: 主要对transformer一些比较难理解的点做了一些整理,希望对读者有所帮助。 前置知识: 深度学习基础练习:从pytorch API出发复现LSTM与LSTMP-CSDN博客 【神经网络】学习笔记十四——Seq2Seq模型-CSDN博客 【官方双语】一…...

141. Sprite标签(Canvas作为贴图)
上节课案例创建标签的方式,是把一张图片作为Sprite精灵模型的颜色贴图,本节给大家演示把Canvas画布作为Sprite精灵模型的颜色贴图,实现一个标签。 注意:本节课主要是技术方案讲解,默认你有Canvas基础,如果没有Canvas基…...

【IDEA】解决总是自动导入全部类(.*)问题
文章目录 问题描述解决方法 我是一名立志把细节说清楚的博主,欢迎【关注】🎉 ~ 原创不易, 如果有帮助 ,记得【点赞】【收藏】 哦~ ❥(^_-)~ 如有错误、疑惑,欢迎【评论】指正探讨,我会尽可能第一时间回复…...

python中的OS模块的基本使用
🎉🎉🎉欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!🙏🙏🙏 文章目录…...

【Qt】QComboBox设置默认显示为空
需求 使用QComboBox,遇到一个小需求是,想要设置未点击出下拉列表时,内容显示为空。并且不想在下拉列表中添加一个空条目。 实现 使用setPlaceholderText()接口。我们先来看下帮助文档: 这里说的是,placeholderText是…...

LeetCode - #139 单词拆分
文章目录 前言摘要1. 描述2. 示例3. 答案题解动态规划的思路代码实现代码解析1. **将 wordDict 转换为 Set**2. **初始化 DP 数组**3. **状态转移方程**4. **返回结果** **测试用例**示例 1:示例 2:示例 3: 时间复杂度空间复杂度总结关于我们 前言 本题由于没有合适答案为以往遗…...

服务器作业4
[rootlocalhost ~]# vim 11.sh #关闭防火墙 systemctl stop firewalld setenforce 0 #1.接收用户部署的服务名称 read -p "服务名称:(nginx)" server_name if [ $server_name ! nginx ];then echo "输入的不是nginx,脚本退出" exit 1 fi # 判断是…...

IOC控制反转---相关的介绍和6大注解解读(类注解+方法注解)
文章目录 1.传统方式造车2.传统方法的弊端3.IOC的引入3.IOC对于图书管理系统进行改进(初识)4.注解的使用说明4.1controller注解4.2service注解4.3component注解4.4关于spring命名的问题4.5component重命名4.6repository注解4.7configuration注解4.8注解之…...

SpringBoot(8)-任务
目录 一、异步任务 二、定时任务 三、邮件任务 一、异步任务 使用场景:后端发送邮件需要时间,前端若响应不动会导致体验感不佳,一般会采用多线程的方式去处理这些任务,但每次都需要自己去手动编写多线程来实现 1、编写servic…...

【机器学习】如何配置anaconda环境(无脑版)
马上就要上机器学习的实验,这里想写一下我配置机器学习的anaconda环境的二三事 一、首先,下载安装包: Download Now | Anaconda 二、打开安装包,一直点NEXT进行安装 这里要记住你要下载安装的路径在哪,后续配置环境…...

java 可以跨平台的原因是什么?
我们对比一个东西就可以了,那就是chrome浏览器。 MacOS/Linux/Windows上的Chrome浏览器,那么对于HTML/CSS/JS的渲染效果都一样的。 我们就可以认为ChromeHTML/CSS/JS是跨平台的。 这里面,HTML/CSS/JS是不变的的,对于一个网页&a…...

Solana应用开发常见技术栈
编程语言 Rust Rust是Solana开发中非常重要的编程语言。它具有高性能、内存安全的特点。在Solana智能合约开发中,Rust可以用于编写高效的合约代码。例如,Rust的所有权系统可以帮助开发者避免常见的内存错误,如悬空指针和数据竞争。通过合理利…...

npm | Yarn | pnpm Node.js包管理器比较与安装
一、包管理器比较 参考原文链接: 2024 Node.js Package Manager 指南:npm、Yarn、pnpm 比较 — 2024 Node.js Package Manager Guide: npm, Yarn, pnpm Compared (nodesource.com) 以下是对 Node.js 的三个包管理工具 npm、Yarn 和 pnpm 的优缺点总结&am…...

Linux下编译MFEM
本文记录在Linux下编译MFEM的过程。 零、环境 操作系统Ubuntu 22.04.4 LTSVS Code1.92.1Git2.34.1GCC11.4.0CMake3.22.1Boost1.74.0oneAPI2024.2.1 一、安装依赖 二、编译代码 附录I: CMakeUserPresets.json {"version": 4,"configurePresets": [{&quo…...

【团购核销】抖音生活服务商家应用快速接入②——商家授权
文章目录 一、前言二、授权流程三、授权Url3.1 Url参数表3.2 授权能力表3.3 源码示例 四、授权回调4.1 添加授权回调接口4.2 授权回调接口源码示例 五、实际操作演示六、参考 一、前言 目的:将抖音团购核销的功能集成到我们自己开发的App和小程序中 【团购核销】抖音…...

django宠物服务管理系统
摘 要 宠物服务管理系统是一种专门为宠物主人和宠物服务提供商设计的软件。它可以帮助用户快速找到附近的宠物医院、宠物美容店、宠物寄养中心等服务提供商,并预订相关服务。该系统还提供了一系列实用的功能。通过使用宠物服务管理系统,用户可以更加方便…...

vue2中使用three.js步骤
1.使用npm 下载依赖这里以0.158.0版本为例 npm install three0.158.0 --save 2. <template><div id"container"></div> </template><script> import * as THREE from three; import { OBJLoader } from three/examples/jsm/loaders/O…...

部落商城App开发笔记 2024.11.21 实现进入app就是短视频
初步效果: 基于图鸟UI二次开发, 这里静态资源没有加载, 我在本机上安装了一个nginx, 需要启动一下. PS C:\dev\nginx-1.26.2> start .\nginx.exe重新刷新就有数据了. 先看看目前的页面吧. 首页. 分类: 发现. 消息. 购物车. 我的. 这个项目是有短视频的功能…...

解决.DS_Store 在项目一致无法排除,.gitignore里也不生效
.DS_Store 是 macOS 操作系统创建的隐藏文件,通常用于存储目录的属性,比如视图设置、图标位置等。它通常不应包含在代码仓库中,因此需要排除它。你提到即使将其添加到 .gitignore 文件中,仍然无法排除它,可能是由于以下…...

MySQL-关键字执行顺序
💖简介 在MySQL中,SQL查询语句的执行遵循一定的逻辑顺序,即使这些关键字在SQL语句中的物理排列可能有所不同。 🌟语句顺序 (8) SELECT (9) DISTINCT<select_list> (1) FROM <left_table> (3) <join_type> JO…...

极客时间《Redis核心技术与实战》开篇词 知识点总结
Redis 主要的数据持久化方式 RDB(Redis Database Backup file) RDB 是 Redis 提供的一种数据快照持久化方式,它会在指定的时间间隔内生成数据集的时间点快照,并将这些快照保存到磁盘上的一个 RDB 文件中。RDB 文件是一个压缩的二…...

TCP并发服务器
端口号快速复用函数 通过getsockopt和setsockopt函数,管理套接字的端口号复用设置。具体操作如下: getsockopt函数 int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);功能:获取套接字的某些选项的属性。…...

Debug-031-近期功能实现小结
由于时间原因,没办法对每个小的功能点进行比较细致的总结,这里统一去记录一下最近的实现了的功能,算是存档备份,为今后开发带来便利和参考。 一、ACEeditor ACEeditor使用手册(一)_ace editor-CSDN博客 AC…...

Consumer Group
不,kafka-consumer-groups.sh 脚本本身并不用于创建 Consumer Group。它主要用于管理和查看 Consumer Group 的状态和详情,比如列出所有的 Consumer Group、查看特定 Consumer Group 的详情、删除 Consumer Group 等。 Consumer Group 是由 Kafka 消费者…...