当前位置: 首页 > news >正文

莘县网站建设费用长春网站建设设计

莘县网站建设费用,长春网站建设设计,什么公司网站建设做的好,系统开发是做什么的useId的介绍 https://zh-hans.react.dev/reference/react/useId useId 是 React 18 引入的一个新 Hook,主要用于生成全局唯一的 ID。在开发中,我们经常需要为元素(如表单元素、模态框等)生成唯一 ID,以便在 JavaScri…

useId的介绍

https://zh-hans.react.dev/reference/react/useId

useId 是 React 18 引入的一个新 Hook,主要用于生成全局唯一的 ID。在开发中,我们经常需要为元素(如表单元素、模态框等)生成唯一 ID,以便在 JavaScript 中进行操作或在 CSS 中进行样式绑定。使用 useId 可以避免手动管理 ID 带来的问题,比如在服务器端渲染(SSR)时客户端和服务器端生成的 ID 不一致。

useId的使用

例子:基本用法

import React, { useId } from 'react';function App() {const id = useId();return (<div><label htmlFor={id}>用户名:</label><input type="text" id={id} /></div>);
}export default App;

例子:处理多个ID

import React, { useId } from 'react';function App() {const baseId = useId();const nameId = `${baseId}-name`;const emailId = `${baseId}-email`;return (<form><label htmlFor={nameId}>姓名:</label><input type="text" id={nameId} /><br /><label htmlFor={emailId}>邮箱:</label><input type="email" id={emailId} /></form>);
}export default App;

例子:在组件树中使用
useId 在组件树中使用时,每个组件实例都会生成不同的 ID。这意味着即使在嵌套组件中多次使用 useId,也不会产生冲突

import React, { useId } from 'react';function InputWithLabel({ labelText }) {const id = useId();return (<div><label htmlFor={id}>{labelText}</label><input type="text" id={id} /></div>);
}function App() {return (<div><InputWithLabel labelText="用户名" /><InputWithLabel labelText="密码" /></div>);
}export default App;

hook 初始化入口

hook是函数组件中的钩子函数。在函数组件渲染的过程中会调用renderWithHooks函数。

renderWithHooks

函数参数含义:

  • current:旧的 Fiber 节点,如果是首次渲染则为 null。
  • workInProgress:当前正在处理的新 Fiber 节点。
  • Component:要渲染的函数式组件,它接收 props 和 secondArg 作为参数,并返回 JSX 元素。
  • props:传递给组件的属性。
  • secondArg:额外的参数。
  • nextRenderLanes:下一次渲染的优先级车道。
function renderWithHooks<Props, SecondArg>(current: Fiber | null,workInProgress: Fiber,Component: (p: Props, arg: SecondArg) => any,props: Props,secondArg: SecondArg,nextRenderLanes: Lanes,
): any {// 确定当前渲染的优先级。renderLanes = nextRenderLanes;// 将 currentlyRenderingFiber 指向 workInProgress,表示当前正在渲染这个 Fiber 节点。currentlyRenderingFiber = workInProgress;// 重置信息workInProgress.memoizedState = null;workInProgress.updateQueue = null;workInProgress.lanes = NoLanes;//钩子调度器,区分是初始化还是更新ReactSharedInternals.H =current === null || current.memoizedState === null? HooksDispatcherOnMount: HooksDispatcherOnUpdate;//调用函数组件let children = Component(props, secondArg);// 调用 finishRenderingHooks 函数,进行一些渲染完成后的清理和处理工作,例如处理副作用钩子的执行等。finishRenderingHooks(current, workInProgress, Component);return children;
}
// renderLanes:表示当前渲染的优先级车道,初始值为 NoLanes(通常为 0),用于标识渲染任务的优先级。
let renderLanes: Lanes = NoLanes;//默认0// 指向当前正在渲染的 Fiber 节点,初始为 null。Fiber 是 React 中的一种数据结构,用于表示组件树中的每个节点。
let currentlyRenderingFiber: Fiber = (null: any);// 当前的钩子
let currentHook: Hook | null = null;//正在处理的钩子
let workInProgressHook: Hook | null = null;

所以初始化用HooksDispatcherOnMount,更新使用HooksDispatcherOnUpdate

HooksDispatcherOnMount

const HooksDispatcherOnMount: Dispatcher = {readContext,use,useCallback: mountCallback,useContext: readContext,useEffect: mountEffect,useImperativeHandle: mountImperativeHandle,useLayoutEffect: mountLayoutEffect,useInsertionEffect: mountInsertionEffect,useMemo: mountMemo,useReducer: mountReducer,useRef: mountRef,useState: mountState,useDebugValue: mountDebugValue,useDeferredValue: mountDeferredValue,useTransition: mountTransition,useSyncExternalStore: mountSyncExternalStore,useId: mountId,
};

HooksDispatcherOnUpdate

const HooksDispatcherOnUpdate: Dispatcher = {readContext,use,useCallback: updateCallback,useContext: readContext,useEffect: updateEffect,useImperativeHandle: updateImperativeHandle,useInsertionEffect: updateInsertionEffect,useLayoutEffect: updateLayoutEffect,useMemo: updateMemo,useReducer: updateReducer,useRef: updateRef,useState: updateState,useDebugValue: updateDebugValue,useDeferredValue: updateDeferredValue,useTransition: updateTransition,useSyncExternalStore: updateSyncExternalStore,useId: updateId,
};

useId初始化

function useId(): string {
//resolveDispatcher 是 React 内部的一个函数,它的作用是获取当前的调度器(dispatcher)const dispatcher = resolveDispatcher();// dispatcher.useId() 调用了调度器对象的 useId 方法。这个方法会生成一个全局唯一的 ID 字符串,并将其返回。return dispatcher.useId();
}

resolveDispatcher

function resolveDispatcher() {// 从 ReactSharedInternals 对象中获取名为 H 的属性,并将其赋值给变量 dispatcher。ReactSharedInternals 是 React 内部使用的一个共享对象,它包含了一些 React 运行时的关键信息和工具。H 属性在这里代表着当前 React 环境下的调度器实例。const dispatcher = ReactSharedInternals.H;// 将获取到的调度器实例 dispatcher 返回给调用者。这样,调用 resolveDispatcher 函数的代码就可以使用这个调度器来执行各种调度相关的操作,比如调用调度器的 useState 方法来处理状态管理。return dispatcher;
}

mountId

mountId 函数是 React 中 useId Hook 在挂载阶段(组件首次渲染)用于生成全局唯一 ID 的核心实现。该函数会根据当前是服务端渲染(SSR)还是客户端渲染的不同情况,生成不同格式的唯一 ID,并将其存储在 Fiber 节点对应的 hook 对象的 memoizedState 属性上,最后返回这个唯一 ID。

function mountId(): string {//创建 hook 对象,将 hook 对象添加到 workInProgressHook 单向链表中,返回最新的 hook 链表const hook = mountWorkInProgressHook();
//getWorkInProgressRoot() 方法获取当前的 FiberRoot 对象const root = ((getWorkInProgressRoot(): any): FiberRoot);//从 FiberRoot 对象 上获取id前缀const identifierPrefix = root.identifierPrefix;let id;// 调用 getIsHydrating() 方法判断是服务端渲染还是客户端渲染if (getIsHydrating()) {//服务端渲染注水(hydrate)阶段生成的唯一 id,以冒号开头,并以冒号结尾,使用大写字母 R 标识该id是服务端渲染生成的id//获取组件树的idconst treeId = getTreeId();// Use a captial R prefix for server-generated ids.id = ':' + identifierPrefix + 'R' + treeId;// localIdCounter 变量记录组件中 useId 的执行次数const localId = localIdCounter++;if (localId > 0) {id += 'H' + localId.toString(32);}id += ':';} else {//客户端渲染生成的唯一 id,以冒号开头,并以冒号结尾,使用小写字母 r 标识该id 是客户端渲染生成的id//全局变量 globalClientIdCounter 记录 useId hook 在组件中的调用次数const globalClientId = globalClientIdCounter++;// globalClientIdCounter初始值为0id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';}// 将生成的唯一 id 存储到 hook 对象的 memoizedState 属性上hook.memoizedState = id;return id;
}

以下代码可以看到useId的返回值的格式

id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
// ':r0:'

如何在挂载的时候加入配置项identifierPrefix

ReactDOM.createRoot(document.getElementById('box'),{identifierPrefix: 'testyoyo'
});
id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
//:testyoyor0:

updateId

当函数组件刷新时,重新构建hook链表时,遇到useId会执行以下代码

function updateId(): string {//  获取当前的 workInProgressHookconst hook = updateWorkInProgressHook();// 从当前的 workInProgressHook 上获取 useId 生成的 id,因此即使组件重新渲染,id 也不会变化const id: string = hook.memoizedState;return id;
}

工具函数 mountWorkInProgressHook

mountWorkInProgressHook 函数主要用于在 React 的渲染过程中,为当前正在处理的 Fiber 节点(currentlyRenderingFiber)挂载一个新的 Hook。
Hook 是 React 中用于在函数组件中使用状态和副作用的机制,这个函数负责初始化 Hook 对象,并将其添加到当前 Fiber 节点的 Hook 链表中。

function mountWorkInProgressHook(): Hook {// 初始化hook对象const hook: Hook = {memoizedState: null,//用于存储当前 Hook 的状态值,在使用 useState 或 useReducer 等钩子时会更新这个值。baseState: null,// 表示状态的基础值,在处理更新队列时会用到。baseQueue: null,// 存储尚未处理的更新队列,通常与 baseState 配合使用。queue: null,// 存储当前 Hook 的更新队列,用于存储状态更新的操作。next: null,// 用于将多个 Hook 对象连接成一个链表,指向下一个 Hook 对象。};// 如果 workInProgressHook 为 null,说明这是当前 Fiber 节点的第一个 Hook。if (workInProgressHook === null) {// 将 currentlyRenderingFiber 的 memoizedState 属性设置为新创建的 Hook 对象,并将 workInProgressHook 也指向这个 Hook 对象。这样,currentlyRenderingFiber 的 memoizedState 就成为了 Hook 链表的头节点。currentlyRenderingFiber.memoizedState = workInProgressHook = hook;} else {// Append to the end of the list// 如果 workInProgressHook 不为 null,说明当前 Fiber 节点已经有其他 Hook 存在。此时,将新创建的 Hook 对象添加到 Hook 链表的末尾。workInProgressHook = workInProgressHook.next = hook;}// 返回当前正在处理的 Hook 对象return workInProgressHook;
}

在这里插入图片描述

export type Hook = {memoizedState: any,baseState: any,baseQueue: Update<any, any> | null,queue: any,next: Hook | null,
};

当前Fiber 节点与 hook 链表的关联关系图

在这里插入图片描述

http://www.cadmedia.cn/news/16187.html

相关文章:

  • 汕头建设吧 百度贴吧sem推广优化
  • 自己可以免费做网站吗seo排名培训公司
  • 国内建设黄色网站策划网络营销活动
  • 信息化建设与政府网站工作汇报陕西seo
  • 2022年近期舆情热点话题宁波seo教学
  • 建设银行重庆分行网站网络市场调研的方法
  • 校园网站集群建设手机端百度收录入口
  • 网站建设报价明细太原网站关键词排名
  • 网站可以只做移动端吗东营网站seo
  • 2022没封的网站免费的线上营销
  • 南宁网站设计制作公司十大网络推广公司
  • 2016企业网站源码东莞网站推广宣传
  • 建设网站价格企业营销管理
  • 电子商务网站建设维护实训报告点击进入官方网站
  • 微网站建设多少钱电工培训内容
  • 网站内容规划流程网络品牌营销
  • 哪家公司网站建设好湖北seo服务
  • 手游app平台排行榜seo全网营销
  • 昆明网站建设云集创chrome谷歌浏览器
  • 自己有网站怎么赚钱seo搜狗排名点击
  • 网站建设接外包流程图seo优化服务是什么
  • 高端网站设计推广v信haotg8怎样做好竞价推广
  • 日照市建设信息网官方网站进入百度首页官网
  • 网站名称格式南宁seo多少钱报价
  • 深圳交易网站建设怎么在百度发广告
  • 佛山企业网站制作推广游戏赚钱的平台有哪些
  • 工厂外贸网站建设爱站网长尾关键词挖掘工具
  • 中山网站建设seo优化营销制作设计百度输入法免费下载
  • html个人简历完整代码佛山百度快速排名优化
  • app平台推广怎么做南京seo关键词优化预订