iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > html >React ref的原理和应用
  • 892
分享到

React ref的原理和应用

2024-04-02 19:04:59 892人浏览 薄情痞子
摘要

本篇内容介绍了“React ref的原理和应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!提到 ref或

本篇内容介绍了“React ref的原理和应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

提到 ref或者 refs 如果你用过React 16以前的版本 第一印象都是用来访问DOM或者修改组件实例的,

正如官网所介绍的这样:

React ref的原理和应用

然后到了React 16.3出现的 createRef 以及16.8 hooks中的  useRef出现时,发现这里的ref好像不仅仅只有之前的绑定到DOM/组件实例的 作用?本文将带你逐一梳理这些知识点,并尝试分析相关源码

前置知识

这部分知识点不是本文重点,每个点展开都非常庞大,了方便本文理解先在这里简单提及。

Fiber架构

Fiber是React更新时的最小单元,是一种包含指针的数据结构,从数据结构上看Fiber架构 ≈ 树 + 链表

Fiber单元是从 jsx createElement之后根据ReactElement生成的,相比  ReactElement,Fiber单元具备动态工作能力。

React 的工作流程

使用chrome perfomance录制一个react应用渲染看函数调用栈会看到下面这张图

React ref的原理和应用

这三块内容分别代表: 1.生成react root节点 2.reconciler 协调生成需要更新的子节点 3.将节点更新commit 到视图

Hooks基础知识

在函数组件中每执行一次use开头的hook函数都会生成一个hook对象。

type Hook = {   memoizedState: any,   // 上次更新之后的最终状态值   queue: UpdateQueue, //更新队列   next, // 下一个 hook 对象 };

其中memoizedState会保存该hook上次更新之后的最终状态,比如当我们使用一次useState之后就会在memoizedState中保存初始值。

React 中大部分 hook 分为两个阶段:第一次初始化时`mount`阶段和更新`update`时阶段

hooks函数的执行分两个阶段 mount和 update,比如 useState只会在初始化时执行一次,下文中将提到的

useImperativeHandle 和 useRef也包括在内。

调试源码

本文已梳理摘取了源码相关的函数,但你如果配合源码调试一起食用效果会更加。

本文基于React v17.0.2。

拉取React代码并安装依赖

将react,scheduler以及react-dom打包为commonjs

yarn build react/index,react-dom/index,scheduler --type node

3.进入build/node_modules/react/cjs 执行yarn link 同理 react-dom

4.在  build/node_modules/react/cjs/react.development.js中加入link标记console以确保检查link状态

5.使用create-react-app创建一个测试应用 并link react,react-dom

ref prop

组件上的ref属性是一个保留属性,你不能把ref当成一个普通的prop属性在一个组件中获取,比如:

const Parent = () => {     return <Child ref={{test:1}}> } const Child = (props) => {   console.log(props);   // 这里获取不到ref属性     return <div></div> }

这个ref去哪里了呢, React本身又对它做了什么呢?

我们知道React的解析是从createElement开始的,找到了下面创建ReactElement的地方,确实有对ref保留属性的处理。

export function createElement(type, config, children) { let propName;   // Reserved names are extracted   const props = {};   let ref = null;   if (config != null) {     if (hasValidRef(config)) {       ref = config.ref;     }     for (propName in config) {       if (         hasOwnProperty.call(config, propName) &&         !RESERVED_PROPS.hasOwnProperty(propName)       ) {         props[propName] = config[propName];       }     }   }   return ReactElement(     type,     key,     ref,     props,     ...   ); }

从createElement开始就已经创建了对ref属性的引用。

createElement之后我们需要构建Fiber工作树,接下来主要讲对ref相关的处理。

React对于不同的组件有不通的处理

先主要关注 FunctionComponent/ClassComponent/HostComponent(原生html标签)

FunctionComponent

function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {       try {         nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);       } finally {         reenableLogs();       }       reconcileChildren(current, workInProgress, nextChildren, renderLanes);       return workInProgress.child; } functin renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes){             children = Component(props, secondArg); // 这里的Component就是指我们的函数组件                 return children; }

我们可以看到函数组件在渲染的时候就是直接执行。

Class组件和原生标签的ref prop

ClassComponent

function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {   ...   {     ...     constructClassInstance(workInProgress, Component, nextProps);         ....   }   var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);     ...   return nextUnitOfWork; } function constructClassInstance(workInProgress, ctor, props) {     ....   var instance = new ctor(props, context);   // 把instance实例挂载到workInProgress stateNode属性上   adoptClassInstance(workInProgress, instance);     .....   return instance; } function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {   // 标记是否有ref更新   markRef(current, workInProgress); } function markRef(current, workInProgress) {   var ref = workInProgress.ref;   if (current === null && ref !== null || current !== null && current.ref !== ref) {     // Schedule a Ref effect     workInProgress.flags |= Ref;   } }

ClassComponent则是通过构造函数生成实例并标记了ref属性。

回顾一下之前提到的React工作流程,既然是要将组件实例或者真实DOM赋值给ref那肯定不能在一开始就处理这个ref,而是根据标记到commit阶段再给ref赋值。

function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {     ....   {     if (finishedWork.flags & Ref) {       commitAttachRef(finishedWork);     }   }   .... } function commitAttachRef(finishedWork) {   var ref = finishedWork.ref;   if (ref !== null) {     var instance = finishedWork.stateNode;     var instanceToUse;     switch (finishedWork.tag) {       case HostComponent:         // getPublicInstance 这里调用了DOM api 返回了DOM对象         instanceToUse = getPublicInstance(instance);         break;       default:         instanceToUse = instance;     }      // 对函数回调形式设置ref的处理     if (typeof ref === 'function') {       {         ref(instanceToUse);       }     } else {       ref.current = instanceToUse;     }   } }

在commit阶段,如果是原生标签则将真实DOM赋值给ref对象的current属性, 如果是class componnet  则是组件instance。

函数组件的ref prop

如果你对function组件未做处理直接加上ref,react会直接忽略并在开发环境给出警告

React ref的原理和应用

函数组件没有实例可以赋值给ref对象,而且组件上的ref prop会被当作保留属性无法在组件中获取,那该怎么办呢?

forwardRef

React提供了一个forwardRef函数 来处理函数组件的 ref prop,用起来就像下面这个示例:

const Parent = () => {     const childRef = useRef(null)   return <Child ref={childRef}/> } const Child = forWardRef((props,ref) => {     return <div>Child</div> }}

这个方法的源码主体也非常简单,返回了一个新的elementType对象,这个对象的render属性包含了原本的这个函数组件,而$$typeof则标记了这个特殊组件类型。

function forwardRef(render) {   ....   var elementType = {     $$typeof: REACT_FORWARD_REF_TYPE,     render: render   }   ....   return elementType;  }

那么React对forwardRef这个特殊的组件是怎么处理的呢

function beginWork(current, workInProgress, renderLanes) {     ...   switch (workInProgress.tag) {     case FunctionComponent:       {        ...         return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderLanes);       }     case ClassComponent:       {                 ....         return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderLanes);       }     case HostComponent:       return updateHostComponent(current, workInProgress, renderLanes);     case ForwardRef:       {                 ....         // 第三个参数type就是forwardRef创建的elementType         return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);       } }    function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {     ....   var render = Component.render;   var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent   var nextChildren;   {         ...     //  将ref引用传入renderWithHooks     nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);     ...   }   workInProgress.flags |= PerfORMedWork;   reconcileChildren(current, workInProgress, nextChildren, renderLanes);   return workInProgress.child; }

可以看到和上面 FunctionComponent的主要区别仅仅是把ref保留属性当成普通属性传入 renderWithHooks方法!

那么又有一个问题出现了,如果只是传了一个ref引用,而没有像Class组件那样可以attach的实例,岂不是没有办法操作子函数组件的行为?

用上面的例子验证一下

const Parent = () => {     const childRef = useRef(null)   useEffect(()=>{     console.log(childref) // { current:null }   })   return <Child ref={childRef}/> } const Child = forwardRef((props,ref) => {     return <div>Child</div> }}                            const Parent = () => {    const childRef = useRef(null)   useEffect(()=>{     console.log(childref) // { current: div }   })   return <Child ref={childRef}/> } const Child = forwardRef((props,ref) => {     return <div ref={ref}>Child</div> }}

结合输出可以看出如果单独使用forwardRef仅仅只能转发ref属性。如果ref最终没有绑定到一个ClassCompnent或者原生DOM上那么这个ref将不会改变。

假设一个业务场景,你封装了一个表单组件,想对外暴露一些接口比如说提交的action以及校验等操作,这样应该如何处理呢?

useImperativeHandle

react为我们提供了这个hook来帮助函数组件向外部暴露属性

先看下效果

const Parent = () => {     const childRef = useRef(null)   useEffect(()=>{     chilRef.current.sayName();// child   })   return <Child ref={childRef}/> } const Child = forwardRef((props,ref) => {   useImperativeHandle(ref,()=>({     sayName:()=>{         console.log('child')     }   }))     return <div>Child</div> }}

看一下该hook的源码部分(以hook mount阶段为例):

useImperativeHandle: function (ref, create, deps) {       currentHookNameInDev = 'useImperativeHandle';       mountHookTypesDev();       checkDepsAreArrayDev(deps);       return mountImperativeHandle(ref, create, deps);  } function mountImperativeHandle(ref, create, deps) {   {     if (typeof create !== 'function') {       error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');     }   } // TODO: If deps are provided, should we skip comparing the ref itself?   var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;   var fiberFlags = Update;   return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps); } function imperativeHandleEffect(create, ref) {   if (typeof ref === 'function') {     var refCallback = ref;     var _inst = create();     refCallback(_inst);     return function () {       refCallback(null);     };   } else if (ref !== null && ref !== undefined) {     var refObject = ref;     {       if (!refObject.hasOwnProperty('current')) {         error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');       }     }         // 这里执行了传给hook的第二个参数     var _inst2 = create();     refObject.current = _inst2;     return function () {       refObject.current = null;     };   } }

其实就是将我们需要暴露的对象及传给useImperativeHandle的第二个函数参数执行结果赋值给了ref的current对象。

同一份引用

到此为止我们大致梳理了组件上ref prop 的工作流程,以及如何在函数组件中使用ref prop,貌似比想象中简单。

上面的过程我们注意到从createElement再到构建WorkInProgess  Fiber树到最后commit的过程,ref似乎是一直在被传递。

中间过程的代码过于庞大复杂,但是我们可以通过一个简单的测试来验证一下。

const isEqualRefDemo = () => {     const isEqualRef = useRef(1)   return <input key="test" ref={isEqualRef}> }

对于 class component 和 原生标签来说 就是 createElement 到 commitAttachRef之前:

React ref的原理和应用

React ref的原理和应用

在createElement里将ref挂载给window对象,然后在commitAttachRef里判断一下这两次的ref是否全等。

React ref的原理和应用

对于函数组件来说就是 createElement 到 hook执行 imperativeHandleEffect 之前:

const Parent = () => {     const childRef = useRef(1)   useEffect(()=>{     chilRef.current.sayName();// child   })   return <Child ref={childRef}/> } const Child = forwardRef((props,ref) => {   useImperativeHandle(ref,()=>({     sayName:()=>{         console.log('child')     }   }))     return <div>Child</div> }}

 React ref的原理和应用

React ref的原理和应用

从createElement添加ref到React整个渲染过程的末尾(commit阶段)被赋值前,这个ref都是同一份引用。

这也正如 ref单词的本意 reference引用一样。

小节总结

1.ref出现在组件上时是一个保留属性

2.ref在组件存在的生命周期内维护了同一个引用(可变对象 MutableObject)

3.当ref挂载的对象是原生html标签时会ref对象的current属性会被赋值为真实DOM  而如果是React组件会被赋值为React"组件实例"

4.ref挂载都在commit阶段处理

创建ref的方式

ref prop相当于在组件上挖了一个“坑” 来承接 ref对象,但是这样还不够我们还需要先创建ref对象

字符串ref & callback ref

这两种创建ref的方式不再赘述,官网以及社区优秀文章可供参考。

https://zh-hans.reactjs.org/docs/refs-and-the-dom.html

Https://blog.logrocket.com/how-to-use-react-createref-ea014ad09dba/

createRef & useRef

createRef

16.3引入了createRef这个api

React ref的原理和应用

createRef的源码就是一个闭包,对外暴露了 一个具有 current属性的对象。

我们一般会这样在class component中使用createRef

class CreateRefComponent extends React.Component {   constructor(props) {     super(props);     this.myRef = React.createRef()   }   componentDidMount() {     this.myRef.current.focus()     console.log(this.myRef.current)     // dom input   }   render() {     return <input ref={this.myRef} />   } }

为什么不能在函数组件中使用createRef

结合第一节的内容以及  createRef的源码,我们发现,这不过就是在类组件内部挂载了一个可变对象。因为类组件构造函数不会被反复执行,因此这个createRef自然保持同一份引用。但是到了函数组件就不一样了,每一次组件更新,  因为没有特殊处理createRef会被反复重新创建执行,因此在函数组件中使用createRef将不能达到只有同一份引用的效果。

const CreateRefInFC = () => {   const valRef = React.createRef();  // 如果在函数组件中使用createRef 在这个例子中点击后ref就会被重新创建因此将始终显示为null   const [, update] = React.useState();   return <div>     value: {valRef.current}     <button onClick={() => {       valRef.current = 80;       update({});     }}>+     </button>   </div> }

 useRef

React 16.8中出现了hooks,使得我们可以在函数组件中定义状态,同时也带来了 useRef

React ref的原理和应用

React ref的原理和应用

再来看moutRef和updateRef所做的事:

function mountRef(initialValue) {   var hook = mountWorkInProgresshook();   {     var _ref2 = {       current: initialValue     };     hook.memoizedState = _ref2;     return _ref2;   } } function updateRef(initialValue) {   var hook = updateWorkInProgressHook();   return hook.memoizedState; }

借助hook数据结构,第一次useRef时将创建的值保存在memoizedState中,之后每次更新阶段则直接返回。

这样在函数组件更新时重复执行useRef仍返回同一份引用。

因此实际上和 createRef一样本质上只是创建了一个 Mutable  Object,只是因为渲染方式的不同,在函数组件中做了一些处理。而挂载和卸载的行为全部交由组件本身来维护。

被扩展的ref

从  createRef开始我们可以看到,ref对象的消费不再和DOM以及组件属性所绑定了,这意味着你可以在任何地方消费他们,这也回答了本文一开始的那个问题。

useRef的应用

解决闭包问题

由于函数组件每次执行形成的闭包,下面这段代码会始终打印1

export const ClosureDemo =  () => {     const [ count,setCount ] = useState(0);     useEffect(()=> {         const interval = setInterval(()=>{           setCount(count+1)         }, 1000)         return () => clearInterval(interval)       }, [])     // count显示始终是1     return <div>{ count }</div> }

将 count 作为依赖传入useEffect可以解决上面这个问题

export const ClosureDemo =  () => {     const [ count,setCount ] = useState(0);     useEffect(()=> {         const interval = setInterval(()=>{           setCount(count+1)         }, 1000)         return () => clearInterval(interval)       }, [count])     return <div>{ count }</div> }

但是这样定时器也会随着count值的更新而被不断创建,一方面会带来性能问题(这个例子中没有那么明显),更重要的一个方面是它不符合我们的开发语义,因为很明显我们希望定时器本身是不变的。

另外一个方式也可以处理这个问题

export const ClosureDemo =  () => {     const [ count,setCount ] = useState(0);     useEffect(()=> {         const interval = setInterval(()=>{           setCount(count=> count + 1) // 使用setSate函数式更新可以确保每次都取到新的值         }, 1000)         return () => clearInterval(interval)       }, [])     return <div>{ count }</div> }

这样做确实可以处理闭包带来的影响,但是仅限于需要使用setState的场景,对数据的修改和触发setState是需要绑定的,这可能会造成不必要的刷新。

使用useRef创建引用

export const ClosureDemo =  () => {     const [ count,setCount ] = useState(0);     const countRef = useRef(0);     countRef.current = count     useEffect(()=> {         const interval = setInterval(()=>{           // 这里将更新count的逻辑和触发更新的逻辑解耦了           if(countRef.current < 5){             countRef.current++           } else {             setCount(countRef.current)           }         }, 1000)         return () => clearInterval(interval)       }, [])     return <div>{ count }</div> }

 封装自定义hooks

useCreation

通过factory函数来避免类似于 useRef(new Construcotr)中构造函数的重复执行

import { useRef } from 'react'; export default function useCreation<T>(factory: () => T, deps: any[]) {   const { current } = useRef({     deps,     obj: undefined as undefined | T,     initialized: false,   });   if (current.initialized === false || !depsAreSame(current.deps, deps)) {     current.deps = deps;     current.obj = factory();     current.initialized = true;   }   return current.obj as T; } function depsAreSame(oldDeps: any[], deps: any[]): boolean {   if (oldDeps === deps) return true;   for (const i in oldDeps) {     if (oldDeps[i] !== deps[i]) return false;   }   return true; }

usePrevious

通过创建两个ref来保存前一次的state

import { useRef } from 'react'; export type compareFunction<T> = (prev: T | undefined, next: T) => boolean; function usePrevious<T>(state: T, compare?: compareFunction<T>): T | undefined {   const prevRef = useRef<T>();   const curRef = useRef<T>();   const needUpdate = typeof compare === 'function' ? compare(curRef.current, state) : true;   if (needUpdate) {     prevRef.current = curRef.current;     curRef.current = state;   }   return prevRef.current; } export default usePrevious;

useClickAway

自定义的元素失焦响应hook

import { useEffect, useRef } from 'react'; export type BasicTarget<T = HTMLElement> =   | (() => T | null)   | T   | null   | MutableRefObject<T | null | undefined>;     export function getTargetElement(   target?: BasicTarget<TargetElement>,   defaultElement?: TargetElement, ): TargetElement | undefined | null {   if (!target) {     return defaultElement;   }   let targetElement: TargetElement | undefined | null;   if (typeof target === 'function') {     targetElement = target();   } else if ('current' in target) {     targetElement = target.current;   } else {     targetElement = target;   }   return targetElement; } // 鼠标点击事件,click 不会监听右键 const defaultEvent = 'click'; type EventType = MouseEvent | TouchEvent; export default function useClickAway(   onClickAway: (event: EventType) => void,   target: BasicTarget | BasicTarget[],   eventName: string = defaultEvent, ) {   // 使用useRef保存回调函数   const onClickAwayRef = useRef(onClickAway);   onClickAwayRef.current = onClickAway;   useEffect(() => {     const handler = (event: any) => {       const targets = Array.isArray(target) ? target : [target];       if (         targets.some((targetItem) => {           const targetElement = getTargetElement(targetItem) as HTMLElement;           return !targetElement || targetElement?.contains(event.target);         }) ) {         return;       }       onClickAwayRef.current(event);     };     document.addEventListener(eventName, handler);     return () => {       document.removeEventListener(eventName, handler);     };   }, [target, eventName]); }

以上自定义hooks均出自ahooks

还有许多好用的自定义hook以及仓库比如react-use都基于useRef自定义了很多好用的hook。

“React ref的原理和应用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: React ref的原理和应用

本文链接: https://www.lsjlt.com/news/67709.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • React ref的原理和应用
    本篇内容介绍了“React ref的原理和应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!提到 ref或...
    99+
    2024-04-02
  • Vue3中的ref和reactive响应式原理解析
    目录1 ref2 isref判断是不是一个ref对象3 shallowref创建一个跟踪自身.value变化的 ref,但不会使其值也变成响应式的4 triggerRef5 cust...
    99+
    2022-11-13
    Vue3 ref和reactive响应式 Vue3 ref和reactive
  • 解析vue3的ref,reactive的使用和原理
    目录1.前言2.比较3.ref源码解析4.reactive源码解析createReactiveObjecthandles的组成get陷阱set陷阱5.总结1.前言 vue3新增了re...
    99+
    2024-04-02
  • React ref的使用示例
    目录什么是 ref 如何使用 ref 放在 dom 元素上放在类组件上 放在函数组件上 总结 写了一段时间的 react,99%都在写 state、prop、useState、use...
    99+
    2024-04-02
  • React的核心原理和用法
    本篇内容介绍了“React的核心原理和用法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 1. ...
    99+
    2024-04-02
  • React ref的使用案例
    本篇内容主要讲解“React ref的使用案例”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React ref的使用案例”吧!什么是 ref官网介绍:在典型的 React 数据流中,props ...
    99+
    2023-06-14
  • vue3响应式原理之Ref用法及说明
    目录一. Ref 用法二. 实现1. ref 函数2. createRef 函数3. RefImpl 类的实现4. trackRefValue 依赖收集5. createDep 创建...
    99+
    2022-12-03
    vue3响应式原理 vue3 Ref vue3响应式
  • React中的ref怎么使用
    这篇文章主要介绍“React中的ref怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“React中的ref怎么使用”文章能帮助大家解决问题。1. ref 的理解与使用对于 Ref 的理解,要从...
    99+
    2023-07-04
  • 如何深入理解React的ref 属性
    目录概述1. Refs 对象的创建1.1 React.createRef()1.2 React.useRef(initialValue)2. ref 属性的使用2.1 为原生DOM元...
    99+
    2024-04-02
  • 详解Ref在React中的交叉用法
    目录一、首先说明下什么是Ref二、ref在hooks中的用法1、ref在hooks中HTMLDom的用法2、ref在hooks中与函数式组件的用法3、ref在hooks中与类组件一同...
    99+
    2024-04-02
  • 在React中应用SOLID原则的方法
    目录1、单一职责原则(SRP)2、开放封闭原则(OCP)3、里氏替换原则(LSP)4、接口隔离原则(ISP)5、依赖倒置原则(DIP)6、小结在面向对象编程(OOP)中,SOLID ...
    99+
    2024-04-02
  • react中怎么应用SOLID原则
    这篇文章主要介绍“react中怎么应用SOLID原则”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“react中怎么应用SOLID原则”文章能帮助大家解决问题。什么是开闭原则?Robert c. Ma...
    99+
    2023-07-02
  • 教你应用 SOLID 原则整理 React 代码之单一原则
    目录什么是单一责任原则?让我们从一个糟糕的例子开始1. 移动数据处理逻辑2. 可重用的数据获取钩子3. 分解 UI 组件让我们回顾一下我们刚刚做了什么总结SOLID 原则的主要是作为...
    99+
    2024-04-02
  • RSA-PSS 算法的原理和应用
    本篇内容主要讲解“RSA-PSS 算法的原理和应用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“RSA-PSS 算法的原理和应用”吧!AS(5):RSA-PSS...
    99+
    2024-04-02
  • React中的ref属性的使用示例详解
    目录ref 简介1. 字符串形式的ref2. create形式的ref3. 回调函数形式的ref总结:ref 简介 React提供的这个ref属性,表示为对组件真正实例的引用,其实就...
    99+
    2023-05-17
    React ref属性使用 React ref属性
  • Template ref在Vue3中的实现原理详解
    目录背景模板的编译setup 函数返回值的处理组件的渲染Template Ref 的注册总结背景 最近我的 Vue3 音乐课程后台问答区频繁出现一个关于 Template ref 在...
    99+
    2024-04-02
  • Vue3响应式对象Reactive和Ref的用法解读
    目录一、内容简介二、Reactive1. 关键源码2. 源码流程分析三、代理拦截操作1. 数组操作2.Get操作3. Set操作4. 其余行为拦截操作四、Ref对象1. 思考一个问题...
    99+
    2024-04-02
  • python多进程multiprocessing的原理和应用
    这篇文章主要介绍“python多进程multiprocessing的原理和应用”,在日常操作中,相信很多人在python多进程multiprocessing的原理和应用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家...
    99+
    2023-06-20
  • 如何理解Vue3中的Refs和Ref
    本篇文章为大家展示了如何理解Vue3中的Refs和Ref,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。小编和大家分享关于Vue3中的数据相应的问题,下面我们来例举一个这样的例子Vue.createA...
    99+
    2023-06-25
  • Cookie的工作原理和应用详解
    目录1. Cookie 原理1.1 Cookie 背景信息1.2 Cookie 工作原理1.3 Cookie 创建、获取、修改1.4 Cookie 共享范围1.5 Cookie 生命...
    99+
    2024-04-02
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作