最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React中的?ref?及原理解析

 更新時間:2025年01月01日 08:27:21   作者:袋鼠云數棧前端  
本章深入探討了React?Ref的用法和原理,還介紹了如何使用useImperativeHandle在函數組件中暴露方法,并詳細解釋了ref的處理邏輯和原理,包括在commit階段更新ref以及在組件卸載時的處理,感興趣的朋友一起看看吧

前言

對于 ref 的理解,我們一部人還停留在用 ref 獲取真實 dom 元素和獲取組件層面上,但實際 ref 除了這兩項功能之外,在使用上還有很多小技巧。本章我們就一起深入探討研究一下 React ref 的用法和原理;本章中所有的源碼節(jié)選來自 16.8 版本

基本概念和使用

此部分將分成兩個部分去分析,第一部分是 ref 對象的創(chuàng)建,第二部分是 React 本身對 ref 的處理;兩者不要混為一談,所謂 ref 對象的創(chuàng)建,就是通過 React.createRef 或者 React.useRef 來創(chuàng)建一個 ref 原始對象。而 React 對 ref 處理,主要指的是對于標簽中 ref 屬性,React 是如何處理以及 React 轉發(fā) ref 。下面來仔細介紹一下。

ref 對象的創(chuàng)建

什么是 ref ?

所謂 ref 對象就是用 createRef 或者 useRef 創(chuàng)建出來的對象,一個標準的 ref 對象應該是如下的樣子:

{
  current: null, // current指向ref對象獲取到的實際內容,可以是dom元素,組件實例。
}

React 提供兩種方法創(chuàng)建 ref 對象

類組件 React.createRef

class Index extends React.Component{
    constructor(props){
       super(props)
       this.currentDom = React.createRef(null)
    }
    componentDidMount(){
        console.log(this.currentDom)
    }
    render= () => <div ref={ this.currentDom } >ref對象模式獲取元素或組件</div>
}

打印

React.createRef 的底層邏輯很簡單。下面一起來看一下:

react/src/ReactCreateRef.js

export function createRef() {
  const refObject = {
    current: null,
  }
  return refObject;
}

createRef 一般用于類組件創(chuàng)建 Ref 對象,可以將 Ref 對象綁定在類組件實例上,這樣更方便后續(xù)操作 Ref。
注意:不要在函數組件中使用 createRef,否則會造成 Ref 對象內容丟失等情況。

函數組件

函數組件創(chuàng)建 ref ,可以用 hooks 中的 useRef 來達到同樣的效果。

export default function Index(){
    const currentDom = React.useRef(null)
    React.useEffect(()=>{
        console.log( currentDom.current ) // div
    },[])
    return  <div ref={ currentDom } >ref對象模式獲取元素或組件</div>
}

react-reconciler/ReactFiberHooks.js

function mountRef<T>(initialValue: T): {current: T} {
  const hook = mountWorkInProgressHook();
  const ref = {current: initialValue};
  hook.memoizedState = ref;
  return ref;
}

useRef 返回一個可變的 ref 對象,其 current 屬性被初始化為傳入的參數(initialValue)。返回的 ref 對象在組件的整個生命周期內保持不變。
這個 ref 對象只有一個current屬性,你把一個東西保存在內,它的地址一直不會變。

拓展和總結

useRef 底層邏輯是和 createRef 差不多,就是 ref 保存位置不相同,類組件有一個實例 instance 能夠維護像 ref 這種信息,但是由于函數組件每次更新都是一次新的開始,所有變量重新聲明,所以 useRef 不能像 createRef 把 ref 對象直接暴露出去,如果這樣每一次函數組件執(zhí)行就會重新聲明 ref,此時 ref 就會隨著函數組件執(zhí)行被重置,這就解釋了在函數組件中為什么不能用 createRef 的原因。
為了解決這個問題,hooks 和函數組件對應的 fiber 對象建立起關聯(lián),將 useRef 產生的 ref 對象掛到函數組件對應的 fiber 上,函數組件每次執(zhí)行,只要組件不被銷毀,函數組件對應的 fiber 對象一直存在,所以 ref 等信息就會被保存下來。

react 對 ref 屬性的處理-標記 ref

首先我們先明確一個問題就是 DOM 元素和組件實例必須用 ref 來獲取嗎?答案肯定是否定的,比如 react 還提供了一個 findDOMNode 方法可以獲取 dom 元素,有興趣的可以私下去了解一下。不過通過 ref 的方式來獲取還是最常用的一種方式。

類組件獲取 ref 二種方式

因為 ref 屬性是字符串的這種方式,react 高版本已經舍棄掉,這里就不再介紹了。

ref 屬性是個函數

class Children extends React.Component{  
    render=()=><div>hello,world</div>
}
/* TODO: Ref屬性是一個函數 */
export default class Index extends React.Component{
    currentDom = null
    currentComponentInstance = null
    componentDidMount(){
        console.log(this.currentDom)
        console.log(this.currentComponentInstance)
    }
    render=()=> <div>
        <div ref={(node)=> this.currentDom = node }  >Ref屬性是個函數</div>
        <Children ref={(node) => this.currentComponentInstance = node  }  />
    </div>
}

打印

當用一個函數來標記 ref 的時候,將作為 callback 形式,等到真實 DOM 創(chuàng)建階段,執(zhí)行 callback ,獲取的 DOM 元素或組件實例,將以回調函數第一個參數形式傳入,所以可以像上述代碼片段中,用組件實例下的屬性 currentDom 和 currentComponentInstance 來接收真實 DOM 和組件實例。

ref 屬性是一個 ref 對象

class Children extends React.Component{  
    render=()=><div>hello,world</div>
}
export default class Index extends React.Component{
    currentDom = React.createRef(null)
    currentComponentInstance = React.createRef(null)
    componentDidMount(){
        console.log(this.currentDom)
        console.log(this.currentComponentInstance)
    }
    render=()=> <div>
         <div ref={ this.currentDom }  >Ref對象模式獲取元素或組件</div>
        <Children ref={ this.currentComponentInstance }  />
   </div>
}

函數組件獲取 ref 的方式(useRef)

const Children = () => {  
  return <div>hello,world</div>
}
const Index = () => {
  const currentDom = React.useRef(null)
  const currentComponentInstance = React.useRef(null)
  React.useEffect(()=>{
    console.log( currentDom ) 
    console.log( currentComponentInstance ) 
  },[])
  return (
    <div>
      <div ref={ currentDom }  >通過useRef獲取元素或者組件</div>
      <Children ref={ currentComponentInstance }  />
   </div>
  )
}

ref 的拓展用法

不得不說的 forwardRef

forwardRef 的初衷就是解決 ref 不能跨層級捕獲和傳遞的問題。 forwardRef 接受了父級元素標記的 ref 信息,并把它轉發(fā)下去,使得子組件可以通過 props 來接受到上一層級或者是更上層級的 ref 。

跨層級獲取

我們把上面的例子改一下

獲取子元素的dom

const Children = React.forwardRef((props, ref) => {
  return <div ref={ref}>hello,world</div>
}) 
const Index = () => {
  const currentDom = React.useRef(null)
  const currentComponentInstance = React.useRef(null)
  React.useEffect(()=>{
    console.log( currentDom ) 
    console.log( currentComponentInstance ) 
  },[])
  return (
    <div>
      <div ref={ currentDom }  >通過useRef獲取元素或者組件</div>
      <Children ref={ currentComponentInstance }  />
   </div>
  )

想要在 GrandFather 組件通過標記 ref ,來獲取孫組件 Son 的組件實例。

// 孫組件
function Son (props){
  const { grandRef } = props
  return <div>
      <div> i am alien </div>
      <span ref={grandRef} >這個是想要獲取元素</span>
  </div>
}
// 父組件
class Father extends React.Component{
  render(){
      return <div>
          <Son grandRef={this.props.grandRef}  />
      </div>
  }
}
const NewFather = React.forwardRef((props,ref)=> <Father grandRef={ref}  {...props} />)
// 爺組件
class GrandFather extends React.Component{
  node = null 
  componentDidMount(){
      console.log(this.node) // span #text 這個是想要獲取元素
  }
  render(){
      return <div>
          <NewFather ref={(node)=> this.node = node } />
      </div>
  }
}

合并轉發(fā)ref

通過 forwardRef 轉發(fā)的 ref 不要理解為只能用來直接獲取組件實例,DOM 元素,也可以用來傳遞合并之后的自定義的 ref

場景:想通過 Home 綁定 ref ,來獲取子組件 Index 的實例 index ,dom 元素 button ,以及孫組件 Form 的實例

// 表單組件
class Form extends React.Component{
  render(){
     return <div>{...}</div>
  }
}
// index 組件
class Index extends React.Component{ 
  componentDidMount(){
      const { forwardRef } = this.props
      forwardRef.current={
          form:this.form,      // 給form組件實例 ,綁定給 ref form屬性 
          index:this,          // 給index組件實例 ,綁定給 ref index屬性 
          button:this.button,  // 給button dom 元素,綁定給 ref button屬性 
      }
  }
  form = null
  button = null
  render(){
      return <div   > 
        <button ref={(button)=> this.button = button }  >點擊</button>
        <Form  ref={(form) => this.form = form }  />  
    </div>
  }
}
const ForwardRefIndex = React.forwardRef(( props,ref )=><Index  {...props} forwardRef={ref}  />)
// home 組件
const Home = () => {
  const ref = useRef(null)
   useEffect(()=>{
       console.log(ref.current)
   },[])
  return <ForwardRefIndex ref={ref} />
}

高階組件轉發(fā)

如果通過高階組件包裹一個原始類組件,就會產生一個問題,如果高階組件 HOC 沒有處理 ref ,那么由于高階組件本身會返回一個新組件,所以當使用 HOC 包裝后組件的時候,標記的 ref 會指向 HOC 返回的組件,而并不是 HOC 包裹的原始類組件,為了解決這個問題,forwardRef 可以對 HOC 做一層處理。

function HOC(Component){
  class Wrap extends React.Component{
     render(){
        const { forwardedRef ,...otherprops  } = this.props
        return <Component ref={forwardedRef}  {...otherprops}  />
     }
  }
  return  React.forwardRef((props,ref)=> <Wrap forwardedRef={ref} {...props} /> ) 
}
class Index1 extends React.Component{
  state={
    name: '222'
  }
  render(){
    return <div>hello,world</div>
  }
}
const HocIndex =  HOC(Index1)
const AppIndex = ()=>{
  const node = useRef(null)
  useEffect(()=>{
    console.log(node.current)  /* Index 組件實例  */ 
  },[])
  return <div><HocIndex ref={node}  /></div>
}

源碼位置 react/src/forwardRef.js

export default function forwardRef<Props, ElementType: React$ElementType>(
  render: (props: Props, ref: React$Ref<ElementType>) => React$Node,
) {
  return {
    $$typeof: REACT_FORWARD_REF_TYPE,
    render,
  };
}

ref 實現(xiàn)組件通信

如果有種場景不想通過父組件 render 改變 props 的方式,來觸發(fā)子組件的更新,也就是子組件通過 state 單獨管理數據層,針對這種情況父組件可以通過 ref 模式標記子組件實例,從而操縱子組件方法,這種情況通常發(fā)生在一些數據層托管的組件上,比如  表單,經典案例可以參考 antd 里面的 form 表單,暴露出對外的 resetFields , setFieldsValue 等接口,可以通過表單實例調用這些 API 。

/* 子組件 */
class Son extends React.PureComponent{
  state={
     fatherMes:'',
     sonMes:'我是子組件'
  }
  fatherSay=(fatherMes)=> this.setState({ fatherMes  }) /* 提供給父組件的API */
  render(){
      const { fatherMes, sonMes } = this.state
      return <div className="sonbox" >
          <p>父組件對我說:{ fatherMes }</p>
          <button className="searchbtn" onClick={ ()=> this.props.toFather(sonMes) }  >to father</button>
      </div>
  }
}
/* 父組件 */
function Father(){
  const [ sonMes , setSonMes ] = React.useState('') 
  const sonInstance = React.useRef(null) /* 用來獲取子組件實例 */
  const toSon =()=> sonInstance.current.fatherSay('我是父組件') /* 調用子組件實例方法,改變子組件state */
  return <div className="box" >
      <div className="title" >父組件</div>
      <p>子組件對我說:{ sonMes }</p>
      <button className="searchbtn"  onClick={toSon}  >to son</button>
      <Son ref={sonInstance} toFather={setSonMes} />
  </div>
}

子組件暴露方法 fatherSay 供父組件使用,父組件通過調用方法可以設置子組件展示內容。
父組件提供給子組件 toFather,子組件調用,改變父組件展示內容,實現(xiàn)父 <-> 子 雙向通信。

函數組件 forwardRef + useImperativeHandle

對于函數組件,本身是沒有實例的,但是 React Hooks 提供了,useImperativeHandle 一方面第一個參數接受父組件傳遞的 ref 對象,另一方面第二個參數是一個函數,函數返回值,作為 ref 對象獲取的內容。一起看一下 useImperativeHandle 的基本使用。

useImperativeHandle 接受三個參數:

第一個參數 ref : 接受 forWardRef 傳遞過來的 ref 。
第二個參數 createHandle :處理函數,返回值作為暴露給父組件的 ref 對象。
第三個參數 deps : 依賴項 deps,依賴項更改形成新的 ref 對象。

const Son = React.forwardRef((props, ref) => {
  const state = {
      sonMes:'我是子組件'
  }
  const [fatherMes, setFatherMes] = React.useState('')
    useImperativeHandle(ref,()=>{
      const handleRefs = {
        fatherSay(fatherMss){            
          setFatherMes(fatherMss)
        }
      }
      return handleRefs
  },[])
  const { sonMes } = state
  return (
    <div>
      <p>父組件對我說: {fatherMes}</p>
      <button  onClick={ ()=> props.toFather(sonMes) }  >to father</button>
    </div>
  ) 
})
/* 父組件 */
function Father(){
  const [ sonMes , setSonMes ] = React.useState('') 
  const sonInstance = React.useRef(null) /* 用來獲取子組件實例 */
  const toSon = () => {
    sonInstance.current.fatherSay('我是父組件')
  }
  return <div className="box" >
      <div className="title" >父組件</div>
      <p>子組件對我說:{ sonMes }</p>
      <button className="searchbtn"  onClick={toSon}  >to son</button>
      <Son ref={sonInstance} toFather={setSonMes} />
  </div>
}

forwardRef + useImperativeHandle 可以完全讓函數組件也能流暢的使用 Ref 通信。其原理圖如下所示:

函數組件緩存數據

函數組件每一次 render ,函數上下文會重新執(zhí)行,那么有一種情況就是,在執(zhí)行一些事件方法改變數據或者保存新數據的時候,有沒有必要更新視圖,有沒有必要把數據放到 state 中。如果視圖層更新不依賴想要改變的數據,那么 state 改變帶來的更新效果就是多余的。這時候更新無疑是一種性能上的浪費。

這種情況下,useRef 就派上用場了,上面講到過,useRef 可以創(chuàng)建出一個 ref 原始對象,只要組件沒有銷毀,ref 對象就一直存在,那么完全可以把一些不依賴于視圖更新的數據儲存到 ref 對象中。這樣做的好處有兩個:

第一個能夠直接修改數據,不會造成函數組件冗余的更新作用。
第二個 useRef 保存數據,如果有 useEffect ,useMemo 引用 ref 對象中的數據,無須將 ref 對象添加成 dep 依賴項,因為 useRef 始終指向一個內存空間,所以這樣一點好處是可以隨時訪問到變化后的值。

清除定時器

const App = () => {
  const [count, setCount] = useState(0)
  let timer;
  useEffect(() => {
    timer = setInterval(() => {
      console.log('觸發(fā)了');
    }, 1000);
  },[]);
  const clearTimer = () => {
    clearInterval(timer);
  }
  return (
    <>
     <button onClick={() => {setCount(count + 1)}}>點了{count}次</button>
      <button onClick={clearTimer}>停止</button>
    </>)
}

但是上面這個寫法有個巨大的問題,如果這個 App 組件里有state變化或者他的父組件重新 render 等原因導致這個 App 組件重新 render 的時候,我們會發(fā)現(xiàn),點擊按鈕停止,定時器依然會不斷的在控制臺打印,定時器清除事件無效了。
為什么呢?因為組件重新渲染之后,這里的 timer 以及 clearTimer 方法都會重新創(chuàng)建,timer 已經不是定時器的變量了。
所以對于定時器,我們都會使用 useRef 來定義變量。

const App = () => {
  const [count, setCount] = useState(0)
  const timer = useRef();
  useEffect(() => {
    timer.current = setInterval(() => {
      console.log('觸發(fā)了');
    }, 1000);
  },[]);
  const clearTimer = () => {
    clearInterval(timer.current);
  }
  return (
    <>
      <button onClick={() => {setCount(count + 1)}}>點了{count}次</button>
      <button onClick={clearTimer}>停止</button>
    </>)
}

ref 原理探究

對于 ref 標簽引用,React 是如何處理的呢? 接下來先來看看一段 demo 代碼

class DomRef extends React.Component{
  state={ num:0 }
  node = null
  render(){
      return <div >
          <div ref={(node)=>{
             this.node = node
             console.log('此時的參數是什么:', this.node )
          }}  >ref元素節(jié)點</div>
          <button onClick={()=> this.setState({ num: this.state.num + 1  }) } >點擊</button>
      </div>
  }
}

控制臺輸出結果

提問: 第一次打印為 null ,第二次才是 div ,為什么會這樣呢? 這樣的意義又是什么呢?

ref 執(zhí)行的時機和處理邏輯

根據 React 的生命周期可以知道,更新的兩個階段 render 階段和 commit 階段,對于整個 ref 的處理,都是在 commit 階段發(fā)生的。之前了解過 commit 階段會進行真正的 Dom 操作,此時 ref 就是用來獲取真實的 DOM 以及組件實例的,所以需要 commit 階段處理。
但是對于 ref 處理函數,React 底層用兩個方法處理:commitDetachRef 和 commitAttachRef ,上述兩次 console.log 一次為 null,一次為 div 就是分別調用了上述的方法。

這兩次正好,一次在 DOM 更新之前,一次在 DOM 更新之后。

第一階段:一次更新中,在 commit 的 mutation 階段, 執(zhí)行commitDetachRef,commitDetachRef 會清空之前ref值,使其重置為 null。
源碼先來看一下

react-reconciler/src/ReactFiberCommitWork.js

function commitDetachRef(current: Fiber) {
  const currentRef = current.ref;
  if (currentRef !== null) {
    if (typeof currentRef === 'function') { /* function獲取方式。 */
      currentRef(null); 
    } else {   /* Ref對象獲取方式 */
      currentRef.current = null;
    }
  }
}

第二階段:DOM 更新階段,這個階段會根據不同的 effect 標簽,真實的操作 DOM 。
第三階段:layout 階段,在更新真實元素節(jié)點之后,此時需要更新 ref

react-reconciler/src/ReactFiberCommitWork.js

function commitAttachRef(finishedWork: Fiber) {
  const ref = finishedWork.ref;
  if (ref !== null) {
    const instance = finishedWork.stateNode;
    let instanceToUse;
    switch (finishedWork.tag) {
      case HostComponent: //元素節(jié)點 獲取元素
        instanceToUse = getPublicInstance(instance);
        break;
      default:  // 類組件直接使用實例
        instanceToUse = instance;
    }
    if (typeof ref === 'function') {
      ref(instanceToUse);  //* function 和 字符串獲取方式。 */
    } else {
      ref.current = instanceToUse; /* ref對象方式 */
    }
  }
}

這一階段,主要判斷 ref 獲取的是組件還是 DOM 元素標簽,如果 DOM 元素,就會獲取更新之后最新的 DOM 元素。上面流程中講了二種獲取 ref 的方式。 如果是 函數式 ref={(node)=> this.node = node } 會執(zhí)行 ref 函數,重置新的 ref 。如果是 ref 對象方式,會更新 ref 對象的 current 屬性。達到更新 ref 對象的目的。

ref 的處理特性

接下來看一下 ref 的一些特性,首先來看一下,上述沒有提及的一個問題,React 被 ref 標記的 fiber,那么每一次 fiber 更新都會調用 commitDetachRef 和 commitAttachRef 更新 Ref 嗎 ?
答案是否定的,只有在 ref 更新的時候,才會調用如上方法更新 ref ,究其原因還要從如上兩個方法的執(zhí)行時期說起

更新 ref

在 commit 階段 commitDetachRef 和 commitAttachRef 是在什么條件下被執(zhí)行的呢 ? 來一起看一下:
commitDetachRef 調用時機

react-reconciler/src/ReactFiberWorkLoop.js

function commitMutationEffects(){
     if (effectTag & Ref) {
      const current = nextEffect.alternate;
      if (current !== null) {
        commitDetachRef(current);
      }
    }
}

commitAttachRef 調用時機

function commitLayoutEffects(){
     if (effectTag &amp; Ref) {
      commitAttachRef(nextEffect);
    }
}

從上可以清晰的看到只有含有 ref tag 的時候,才會執(zhí)行更新 ref,那么是每一次更新都會打 ref tag 嗎? 跟著我的思路往下看,什么時候標記的 ref .

react-reconciler/src/ReactFiberBeginWork.js

function markRef(current: Fiber | null, workInProgress: Fiber) {
  const ref = workInProgress.ref;
  if (
    (current === null && ref !== null) ||      // 初始化的時候
    (current !== null && current.ref !== ref)  // ref 指向發(fā)生改變
  ) {
    workInProgress.effectTag |= Ref;
  }
}

首先 markRef 方法執(zhí)行在兩種情況下:
第一種就是類組件的更新過程
第二種就是更新 HostComponent 的時候
markRef 會在以下兩種情況下給 effectTag 標記 ref,只有標記了 ref tag 才會有后續(xù)的 commitAttachRef 和 commitDetachRef 流程。( current 為當前調和的 fiber 節(jié)點 )

第一種 current === null && ref !== null:就是在 fiber 初始化的時候,第一次 ref 處理的時候,是一定要標記 ref 的。
第二種 current !== null && current.ref !== ref:就是 fiber 更新的時候,但是 ref 對象的指向變了。

所以回到最初的那個 DomRef 組件,為什么每一次按鈕,都會打印 ref ,那么也就是 ref 的回調函數執(zhí)行了,ref 更新了。每一次更新的時候,都給 ref 賦值了新的函數,那么 markRef 中就會判斷成 current.ref !== ref,所以就會重新打 Ref 標簽,那么在 commit 階段,就會更新 ref 執(zhí)行 ref 回調函數了。
要想解決這個問題,我們把 DomRef 組件做下修改:

 class DomRef extends React.Component{
    state={ num:0 }
    node = null
    getDom= (node)=>{
        this.node = node
        console.log('此時的參數是什么:', this.node )
     }
    render(){
        return <div >
            <div ref={this.getDom}>ref元素節(jié)點</div>
            <button onClick={()=> this.setState({ num: this.state.num + 1  })} >點擊</button>
        </div>
    }
}

function DomRef () {
  const [num, setNum] = useState(0)
  const node = useRef(null)
      return (
      <div >
          <div ref={node}>ref元素節(jié)點</div>
          <button onClick={()=> {
            setNum(num + 1)
            console.log(node)
          }} >點擊</button>
      </div>
    )
}

卸載 ref

上述講了 ref 更新階段的特點,接下來分析一下當組件或者元素卸載的時候,ref 的處理邏輯是怎么樣的。

react-reconciler/src/ReactFiberCommitWork.js

function safelyDetachRef(current) {
  const ref = current.ref;
  if (ref !== null) {
    if (typeof ref === 'function') {  // 函數式 
        ref(null)
    } else {
      ref.current = null;  // ref 對象
    }
  }
}

被卸載的 fiber 會被打成 Deletion effect tag ,然后在 commit 階段會進行 commitDeletion 流程。對于有 ref 標記的 ClassComponent (類組件) 和 HostComponent (元素),會統(tǒng)一走 safelyDetachRef 流程,這個方法就是用來卸載 ref。

總結

  • ref 對象的二種創(chuàng)建方式
  • 兩種獲取 ref 方法
  • 介紹了一下forwardRef 用法
  • ref 組件通信-函數組件和類組件兩種方式
  • useRef 緩存數據的用法
  • ref 的處理邏輯原理

到此這篇關于React中的 ref 及原理淺析的文章就介紹到這了,更多相關React ref 原理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用React實現(xiàn)輪播效果組件示例代碼

    使用React實現(xiàn)輪播效果組件示例代碼

    React剛出來不久,組件還比較少,不像jquery那樣已經有很多現(xiàn)成的插件了,于是自己寫了一個基于React的輪播效果組件,現(xiàn)在分享給大家,有需要的可以參考借鑒。
    2016-09-09
  • React?Fiber?鏈表操作及原理示例詳解

    React?Fiber?鏈表操作及原理示例詳解

    這篇文章主要為大家介紹了React?Fiber?鏈表操作原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • 解決React報錯Rendered more hooks than during the previous render

    解決React報錯Rendered more hooks than during

    這篇文章主要為大家介紹了React報錯Rendered more hooks than during the previous render解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • react中的DOM操作實現(xiàn)

    react中的DOM操作實現(xiàn)

    某些情況下需要在典型數據流外強制修改子代。要修改的子代可以是 React 組件實例,也可以是 DOM 元素。這時就要用到refs來操作DOM,本文詳細的介紹一下使用,感興趣的可以了解一下
    2021-06-06
  • react基于Ant Desgin Upload實現(xiàn)導入導出

    react基于Ant Desgin Upload實現(xiàn)導入導出

    本文主要介紹了react基于Ant Desgin Upload實現(xiàn)導入導出,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • 在?React?項目中全量使用?Hooks的方法

    在?React?項目中全量使用?Hooks的方法

    這篇文章主要介紹了在?React?項目中全量使用?Hooks,使用 Hooks 能為開發(fā)提升不少效率,但并不代表就要拋棄 Class Component,依舊還有很多場景我們還得用到它,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2022-10-10
  • React19 Diff 算法的具體實現(xiàn)

    React19 Diff 算法的具體實現(xiàn)

    本文主要介紹了React19 Diff 算法的具體實現(xiàn),該算法用于高效地更新虛擬DOM,它通過優(yōu)化傳統(tǒng)樹diff算法,將復雜度從O(n^3)降低到O(n),感興趣的可以了解一下
    2026-05-05
  • React自定義Hook-useForkRef的具體使用

    React自定義Hook-useForkRef的具體使用

    本文主要介紹了React自定義Hook-useForkRef的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • React前端渲染優(yōu)化--父組件導致子組件重復渲染的問題

    React前端渲染優(yōu)化--父組件導致子組件重復渲染的問題

    本篇文章是針對父組件導致子組件重復渲染的優(yōu)化方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React純前端模擬實現(xiàn)登錄鑒權

    React純前端模擬實現(xiàn)登錄鑒權

    這篇文章主要為大家詳細介紹了React純前端模擬實現(xiàn)登錄鑒權的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-04-04

最新評論

滁州市| 蓬莱市| 马鞍山市| 张家港市| 陇西县| 盐池县| 台南市| 永丰县| 曲松县| 定日县| 天等县| 武穴市| 乐清市| 翁牛特旗| 宁河县| 永年县| 阿合奇县| 永昌县| 巫山县| 吉安县| 察哈| 博爱县| 汪清县| 呈贡县| 浦东新区| 习水县| 青浦区| 阳东县| 凌源市| 从化市| 侯马市| 九江市| 嘉黎县| 绥化市| 崇义县| 新营市| 洪洞县| 桦南县| 建瓯市| 麻江县| 大荔县|