精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

來自 React 19 的背刺:ForwardRef 被無情拋棄

開發 前端
在面向對象編程中,IOC (Inversion of Control) 控制反轉是一個非常高級的概念。它是一種設計理念,在減少對象之間的耦合關系上有非常重要的作用。

在之前的版本中,forwardRef 一直是我最愛用的 ref 之一。它在封裝組件時非常有用??墒侨f萬沒想到,由于使用方式稍微麻煩了一點,在新的版本中,直接被 React 19 背刺一刀,實現同樣的功能,以后可以不用它了.... forwardRef 被無情拋棄。

本文主要內容包括如下幾個部分。

  • React 中的 控制反轉 IOC。
  • forwardRef 基礎知識。
  • React 19 中 ref 機制更改,forwardRef 被無情拋棄。
  • useImperativeHandle 與 ref 的新配合。

一、React 中的控制反轉

在面向對象編程中,IOC (Inversion of Control) 控制反轉是一個非常高級的概念。它是一種設計理念,在減少對象之間的耦合關系上有非常重要的作用。

?

許多前端雖然對其有所耳聞,但說實話,能理解的并不多。甚至很對前端對解耦這個概念都是一頭霧水。

IOC 的設計理念里,有三個角色,一個角色是容器 C,一個角色是被控制者 B,一個角色是控制者 A,許多時候,在代碼開發中,控制者 A 直接去控制對象 B,會導致 B 被多次實例化而從讓代碼邏輯變得更加復雜。因此 IOC 的理念是讓 控制者 A 失去對 B 的直接控制權,它只能與容器交互。從而將 A 與 B 的直接聯系隔離開。

這樣說可能會有點繞,但是呢,我們使用一個大家經常使用的代碼來說明一下,你一下就能明白。

const ref = useRef()
<InputNumber ref={ref} />
ref.current.focus()

在這個案例里,我們的目標是直接獲取到 input 對象,并且調用它的 focus 方法,讓 input 獲得焦點。

var input = document.getElementById('input')
input.focus()

但是在模塊的劃分上,input 元素本身并不屬于當前模塊/組件,因此,調用 input 方法的行為,其實是屬于一種混亂。除非我們不做解耦和封裝。

因此,在 React 的組件封裝中,并不支持直接獲取到 input 的引用,而是以一種傳入控制器的方式來調用它。在這個場景里:

input 對象本身是被調用者
InputNumber 組件是容器
ref 是控制器

當前組件利用 ref 來調用 input。從而讓代碼的解耦變得非常合理。可擴展性也很強。

?

注意一些概念上的區分:控制反轉是一種設計思維,依賴注入是控制反轉的一種具體實現,在 React 中,ref 也是一種控制反轉的具體實現。

所以不要聽著別人吹控制反轉就覺得牛,你可能也天天在用。

二、forwardRef 基礎知識

forwardRef 能夠幫助 React 組件傳遞 ref?;蛘哒f是內部對象控制權的轉移與轉發。它接收一個組件作為參數。

import { forwardRef } from 'react';

function MyInput(props, ref) {
  // ...
}

const InputNumber = forwardRef(MyInput);

這里需要注意的是,我們需要把 ref 放在自定義組件的參數中。

function MyInput(props, ref) {
  // ...
}

forwardRef 返回一個可渲染的函數組件。因此,我們可以通過一個簡單的案例完善上面的代碼。

function MyInput(props, ref) {
  return (
    <label>
      {props.label}
      <input ref={ref} />
    </label>
  );
}

const InputNumber = forwardRef(MyInput)

所以呢,在 React 的開發中,forwardRef 能夠幫助我們實現更良好的解耦,這也是我一直非常喜歡使用 forwardRef 的原因。

三、ref 機制更改,forwardRef 被無情拋棄

但是,在 React 19 中,forwardRef 被直接背刺,由于 ref 傳遞機制的更改,我們可以不用 forwardRef 也能做到同樣的事情了。

首先,在聲明組件時,ref 不再獨立成為一個參數,而是作為 props 屬性中的一個屬性。

function MyInput(props) {
  return (
    <label>
      {props.label}
      <input ref={props.ref} />
    </label>
  );
}

其次,代碼這樣寫了之后,就可以直接在父組件中,通過 ref 拿到 input 的控制權。

function Index() {
  const input = useRef(null)

  function __clickHandler() {
    input.current.focus()
  }

  return (
    <div>
      <button onClick={__clickHandler}>
        點擊獲取焦點
      </button>
      <MyInput ref={input} />
    </div>
  )
}

在父組件中的使用與以前一樣,但是子組件由于不再需要 forwardRef,變得更加簡單了。

四、useImperativeHandle 與 ref 的新配合

除了直接拿到元素對象本身就已經存在的 ref,我們還可以通過 useImperativeHandle 來自定義 ref 控制器能執行哪些方法

useImperativeHandle 接收三個參數,分別是:

  • ref: 組件聲明時傳入的 ref。
  • createHandle: 回調函數,需要返回 ref 引用的對象,我們也是在這里重寫 ref 引用。
  • deps: 依賴項數組,可選。state,props 以及內部定義的其他變量都可以作為依賴項,React 內部會使用 Object.is 來對比依賴項是否發生了變化。依賴項發生變化時,createHandle 會重新執行,ref 引用會更新。如果不傳入依賴項,那么每次更新 createHandle 都會重新執行。

在官方文檔中,有這樣一個案例,演示效果如圖所示,當我點擊按鈕時,下方的 input 自動獲取焦點,并且中間的滾動條滾動到最底部。

我們結合新的 ref 傳遞機制和 useImperativeHandle 一起來分析一下這個案例應該怎么實現。

!

思考時,請一定要把封裝的思維帶入進來,否則可能很難感受到這樣做在解耦上的具體好處

首先我們先進行組件拆分,將整個內容拆分為按鈕部分與信息部分,信息部分主要負責信息的展示與輸入,因此頁面組件大概長這樣

<>
  <button>Write a comment</button>
  <Post />
</>

我們期望點擊按鈕時,信息部分的輸入框自動獲取焦點,信息部分的信息展示區域能滾動到最底部,因此整個頁面組件的代碼可以表示為如下:

import { useRef } from 'react';
import Post from './Post.js';

export default function Page() {
  const postRef = useRef(null);

  function handleClick() {
    postRef.current.scrollAndFocusAddComment();
  }

  return (
    <>
      <button onClick={handleClick}>
        Write a comment
      </button>
      <Post ref={postRef} />
    </>
  );
}

再來思考信息部分。

信息部分 Post 又分為兩個部分,分別是信息展示部分與信息輸入部分。此時這兩個部分的 ref 要透傳給 Post,并最終再次透傳給頁面組件。因此他們的組件結構應該長這樣。

<>
  <article>
    <p>Welcome to my blog!</p>
  </article>
  <CommentList ref={commentsRef} />
  <AddComment ref={addCommentRef} />
</>

這個時候,有一個需要考慮的點就是,有兩個對象需要被控制,因此我們需要借助 useImperativeHandle 來自定義控制器,并在控制的方法中,整合他們。

useImperativeHandle(ref, () => {
  return {
    scrollAndFocusAddComment() {
      commentsRef.current.scrollToBottom();
      addCommentRef.current.focus();
    }
  };
}, []);

ref 的傳遞,只需要把它看成是一個普通的 props 即可,因此,Post 組件完整代碼如下:

const Post = ({ref}) => {
  const commentsRef = useRef(null);
  const addCommentRef = useRef(null);

  useImperativeHandle(ref, () => {
    return {
      scrollAndFocusAddComment() {
        commentsRef.current.scrollToBottom();
        addCommentRef.current.focus();
      }
    };
  }, []);

  return (
    <>
      <article>
        <p>Welcome to my blog!</p>
      </article>
      <CommentList ref={commentsRef} />
      <AddComment ref={addCommentRef} />
    </>
  );
}

同樣的道理,我們只需要把 CommentList 與 AddComment 的 ref 傳遞出來就可以了。

所以信息展示部分 CommentList 組件的代碼為。

import { useRef, useImperativeHandle } from 'react';

const CommentList = ({ref}) => {
  const divRef = useRef(null);

  useImperativeHandle(ref, () => {
    return {
      scrollToBottom() {
        const node = divRef.current;
        node.scrollTop = node.scrollHeight;
      }
    };
  }, []);

  let comments = [];
  for (let i = 0; i < 50; i++) {
    comments.push(<p key={i}>Comment #{i}</p>);
  }

  return (
    <div className="CommentList" ref={divRef}>
      {comments}
    </div>
  );
};

export default CommentList;

信息輸入部分 AddComment 的代碼為。

function AddComment(props) {
  return (
    <input 
      placeholder="Add comment..." 
      ref={props.ref} 
    />
  )
};

export default AddComment;

與之前相比,確實要簡單了許多。

五、總結

如果你對封裝解耦比較重視,那么你一定能明顯感受到,ref 與 useImperativeHandle 的結合能發揮的想象空間遠不止于此,這種方式給 React 提供了一種擴展 React 能力的重要手段,因此,當你成為 React 高手之后,你一定會非常喜歡使用它們,他們的組合能讓 React 項目變得更加多樣化。

責任編輯:姜華 來源: 這波能反殺
相關推薦

2019-11-13 10:35:27

React Conf前端總結

2018-04-27 13:20:12

Java 8Java 9Java 10

2021-02-18 23:31:42

Starlink通信擴張

2023-03-28 15:36:43

智能汽車汽車智能化

2025-07-15 13:35:11

2014-05-21 09:47:23

2024-09-06 17:26:49

2025-04-09 10:41:43

2009-09-22 08:56:54

MySQLOracle

2020-04-24 09:14:21

術語網絡安全黑客

2023-09-14 19:15:21

2015-10-10 16:02:36

React NativAndroid

2023-06-25 07:45:52

2010-10-29 11:01:11

簡歷

2011-09-08 14:03:36

2022-05-05 08:25:22

模型OpenAI代碼

2022-07-11 08:20:49

DDoS攻擊網絡攻擊

2023-06-13 14:05:56

ChatGPT數據

2014-01-09 10:19:43

大數據

2021-02-26 07:46:09

WebDAV文件管理
點贊
收藏

51CTO技術棧公眾號

国产免费av观看| 成人小视频免费看| 国产精品电影| 99精品在线免费| 国产精品久久9| 中文字幕在线2021| 久久这里只有精品一区二区| 欧美小视频在线观看| 亚洲综合视频一区| 丰满人妻av一区二区三区| 午夜在线一区| 欧美老少做受xxxx高潮| 国产高清自拍视频| crdy在线观看欧美| 色婷婷综合视频在线观看| 一区二区三区四区五区精品| www.精品视频| 奇米一区二区三区av| 蜜月aⅴ免费一区二区三区 | 一区二区电影免费观看| 国产精品色在线| 国产视频在线观看一区| 91成人一区二区三区| 国产亚洲午夜| 欧美日韩国产成人高清视频| 天天干天天舔天天操| 成人av激情人伦小说| 欧美日韩黄色一区二区| 蜜臀av无码一区二区三区| 69久久精品| 91视频免费播放| 成人欧美视频在线| 国产熟女精品视频| 麻豆精品久久久| 日本久久中文字幕| 可以免费看的av毛片| 欧美女激情福利| 色婷婷综合久久久久| 97伦伦午夜电影理伦片| 不卡的国产精品| 欧美性极品少妇| 国产美女三级视频| 啊啊啊久久久| 一区二区三区日韩欧美| 免费久久久久久| 在线观看完整版免费| 国产欧美一区二区精品性| 久久久久国产精品视频| 日韩一级免费视频| 成人不卡免费av| 国产精品一区二区不卡视频| 国产xxxx孕妇| 国产精品99久久久久久有的能看| 国产日韩在线精品av| 奴色虐av一区二区三区| 玖玖在线精品| 国产成人一区二区三区| 成年人视频免费| 日韩一区精品字幕| 国产精品天天狠天天看| 一本色道久久综合无码人妻| 久久国产欧美日韩精品| 国产欧美日韩中文字幕| 国产精品永久久久久久久久久| 麻豆一区二区在线| 91老司机精品视频| 国产黄色高清视频| 成人国产在线观看| 精品视频在线观看| 男人天堂资源在线| 中文字幕第一区综合| 伊人久久大香线蕉av一区| 黄网站免费在线观看| 亚洲一区二区成人在线观看| 无码av天堂一区二区三区| 草草在线视频| 日本韩国一区二区| 欧美视频亚洲图片| 国产96在线亚洲| 亚洲欧美第一页| 激情无码人妻又粗又大| 亚洲欧美亚洲| 91精品国产乱码久久久久久久久| 中文在线第一页| 美女视频网站黄色亚洲| 成人观看高清在线观看免费| www.com欧美| 91蜜桃免费观看视频| 先锋影音一区二区三区| 污片在线免费观看| 色综合久久中文综合久久97 | 国产综合色在线视频区| 国产91视觉| 国产一区电影| 亚洲精品国产品国语在线app| 波多野结衣家庭教师在线| 日韩不卡免费高清视频| 日韩视频在线你懂得| 亚洲国产欧美视频| 国产高清一区二区| 91精品国产成人| 国产乱人乱偷精品视频| 久久综合九色综合97婷婷| 椎名由奈jux491在线播放| 国产www视频在线观看| 在线这里只有精品| 午夜不卡久久精品无码免费| 不卡中文字幕| 91高清视频在线免费观看| 99成人精品视频| 国产成人精品亚洲日本在线桃色 | 人人狠狠综合久久亚洲婷| 久久69精品久久久久久久电影好 | 亚洲主播在线| 91在线视频成人| 黄网站在线观看| 亚洲国产综合91精品麻豆| 日韩一区二区三区不卡视频| 欧美日韩一区二区三区四区不卡| 久久精品国产一区二区电影| 天干夜夜爽爽日日日日| 成人v精品蜜桃久久一区| 老汉色影院首页| 韩国精品视频在线观看| 亚洲美女喷白浆| 国产乡下妇女做爰| 国产精品2024| 中国一区二区三区| 99亚洲伊人久久精品影院| 亚洲美女自拍视频| 青青国产在线观看| 成人激情小说网站| 天天做天天躁天天躁| 高清一区二区| 久久久国产精品视频| 懂色av中文字幕| 久久久国际精品| 日韩黄色片视频| 窝窝社区一区二区| 欧美一级视频在线观看| 三级视频在线看| 亚洲一区二区三区不卡国产欧美| 国内自拍第二页| 亚洲草久电影| 成人有码视频在线播放| 日本在线人成| 4438成人网| 国产成人综合在线视频| 韩国成人在线视频| 欧美少妇一级片| 日本综合精品一区| 欧美国产日韩免费| 免费看国产片在线观看| 亚洲午夜私人影院| 制服丝袜第一页在线观看| 精品成人免费| 久久综合九色综合久99| 免费日韩电影| 中文字幕亚洲欧美一区二区三区| 69xxxx国产| 国产精品麻豆欧美日韩ww| 国产一伦一伦一伦| 国产精品成人一区二区不卡| 91久久精品美女| 污污视频在线| 精品久久一区| 有码一区二区三区| 337p日本欧洲亚洲大胆张筱雨| 女人香蕉久久**毛片精品| 国产精品国产一区二区| 3344国产永久在线观看视频| 日韩成人av一区| 四虎成人在线观看| 国产精品传媒在线| 亚洲av综合色区无码另类小说| 国内自拍一区| 欧美欧美一区二区| 午夜精品久久久久久毛片| 欧美老妇交乱视频| 欧美婷婷久久五月精品三区| 欧美日韩亚洲综合| 免费网站看av| 国产香蕉久久精品综合网| www.污污视频| 亚洲精品日本| 亚洲欧美日韩国产成人综合一二三区| 国产视频网站一区二区三区| 久久久免费精品| 国产视频第一页在线观看| 欧美一级在线观看| 天天操夜夜操视频| 亚洲欧美视频在线观看视频| 99re久久精品国产| 毛片av中文字幕一区二区| 六月婷婷激情综合| 欧美色图一区| 国产精品综合久久久久久| 成人一区视频| 992tv在线成人免费观看| 乱人伦中文视频在线| 亚洲国产黄色片| 一区二区国产欧美| 欧美日韩一二三四五区| av激情在线观看| 久久青草国产手机看片福利盒子 | 色在线中文字幕| 久久精品中文字幕电影| 毛片在线播放网址| 精品国产一区二区亚洲人成毛片 | 视频一区二区三区入口| 黄网站色视频免费观看| 全球成人免费直播| 免费日韩电影在线观看| 午夜在线视频观看| 欧美.www| 国产高清精品一区二区三区| 日韩三区免费| 91黑丝在线观看| 丝袜综合欧美| 中文字幕自拍vr一区二区三区| 午夜视频免费看| 日韩三级精品电影久久久| 中文文字幕一区二区三三| 黄色一区二区三区| 欧美成人综合色| 中文字幕在线不卡一区二区三区| 久久丫精品国产亚洲av不卡| 国产河南妇女毛片精品久久久| 欧美午夜aaaaaa免费视频| 国产精品一国产精品k频道56| 日韩精品一区二区在线视频| 99精品视频在线观看播放| 亚洲7777| 日韩精品dvd| 日韩片电影在线免费观看| 亚洲精品中文字幕99999| 国产精品theporn88| 精品久久国产一区| 91精品在线一区| 日韩在线你懂得| 国产在线精品播放| 久久久精品一区二区毛片免费看| 国产精品第一视频| 日韩一区二区三区在线免费观看| 日本免费久久高清视频| 欧美电影免费看| 国产mv免费观看入口亚洲| 另类图片综合电影| 国产精品福利在线| 性感美女一区二区在线观看| 国产成人aa精品一区在线播放| 最近在线中文字幕| 日韩免费观看在线观看| 肉色欧美久久久久久久免费看| 亚洲一本视频| a级片一区二区| 国户精品久久久久久久久久久不卡| 亚洲自拍偷拍一区二区三区| 欧美国产先锋| 成品人视频ww入口| 国产一区二区三区成人欧美日韩在线观看| 欧美二区在线视频| 日日噜噜夜夜狠狠视频欧美人| 日韩免费高清在线| 麻豆91在线播放| 爱情岛论坛亚洲自拍| 国产成人免费视频一区| 性欧美丰满熟妇xxxx性久久久| 91亚洲精品一区二区乱码| 丝袜美腿中文字幕| 国产精品―色哟哟| 一级黄色录像视频| 精品二区三区线观看| 国产免费一级视频| 欧美日韩1234| 亚洲精选一区二区三区| 亚洲精品国产精品国产自| 国产永久免费高清在线观看视频| 这里精品视频免费| 色爱综合区网| 欧洲成人免费视频| 深夜福利亚洲| 国外成人免费视频| 欧美自拍偷拍| 久久这里只有精品8| 久久经典综合| 日本特黄在线观看| 久久综合色婷婷| 国产午夜精品理论片在线| 亚洲国产aⅴ天堂久久| 亚洲精品一区二三区| 日韩一区二区三区高清免费看看 | 国产美女无遮挡永久免费| 日韩一区二区三区三四区视频在线观看| 丰满人妻一区二区三区无码av| 日韩精品在线视频观看| 麻豆传媒在线完整视频| 国产91精品久| 懂色av色香蕉一区二区蜜桃| 久草精品电影| 中文字幕一区二区三区在线视频| 啊啊啊一区二区| 国产一区二区三区蝌蚪| 精品夜夜澡人妻无码av| 1024成人网色www| 亚洲天堂男人av| 亚洲精品一区二区三区影院 | 国内自拍欧美| 秋霞毛片久久久久久久久| 精品999网站| 日本55丰满熟妇厨房伦| 欧美国产日韩一二三区| 亚洲 欧美 日韩 综合| 欧美一区二区三区视频| 国产三级在线免费观看| 性欧美xxxx交| 日韩视频一区二区三区四区| 秋霞在线观看一区二区三区| 亚洲久久在线| 老女人性生活视频| 国产精品丝袜久久久久久app| 天天操天天摸天天干| 精品成人在线观看| av在线导航| 国产主播喷水一区二区| 日本不卡电影| 欧美日韩在线成人| 2021国产精品久久精品| 日操夜操天天操| 欧美成人高清电影在线| 黄色网页在线免费看| 国产美女精品免费电影| 欧美一区二区三| 国产高清视频网站| 久久精品视频免费| 麻豆av一区二区三区久久| 丁香花在线电影| 99久久99久久精品国产片| 亚洲精品tv久久久久久久久久| 五月婷婷狠狠操| 国产天堂亚洲国产碰碰| 日韩精品一区二区亚洲av| 日韩精品视频免费在线观看| a级片在线免费观看| 国产日韩精品推荐| 亚洲精品123区| 国产黄色三级网站| 欧美性xxxx极品hd欧美风情| 头脑特工队2在线播放| 97视频在线播放| 希岛爱理av免费一区二区| 欧美日韩亚洲一| 91丨九色丨国产丨porny| wwwxxx亚洲| 亚洲精品视频在线播放| 亚洲最大成人| 亚洲第一在线综合在线| 美女视频网站久久| 黄色香蕉视频在线观看| 日韩三级高清在线| 国产自产自拍视频在线观看| 3d动漫啪啪精品一区二区免费 | 国产精品suv一区| 亚洲系列中文字幕| 日本欧美在线| www.夜夜爱| 91在线国产观看| 在线观看国产区| 久久精品亚洲热| 91蝌蚪精品视频| 免费黄色日本网站| 国产日韩欧美精品一区| 97国产精品久久久| 久久久久久久久久亚洲| 亚洲精品进入| 九九九九九国产| 亚洲国产精品一区二区www在线 | 伊人青青综合网站| 国产精区一区二区| 免费国产黄色网址| 日本一区二区三区国色天香 | 美日韩精品视频| 五月天精品在线| 日韩欧美黄色影院| 在线日韩影院| 综合操久久久| av中文一区二区三区| 国产精品国产精品国产| 欧美老妇交乱视频| 国产综合久久久| 亚洲成人激情小说| 在线视频观看一区| 69xxx在线| 日本不卡免费新一二三区| 国产酒店精品激情| jizz国产在线观看| 欧美夫妻性视频| 欧美日韩中文一区二区| 一级黄色免费视频| 精品视频一区二区三区免费|