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

React高手都善于使用useImprativeHandle

開發 前端
在 React Hooks 中,useImperativeHandle 是一個非常簡單的 Hook,他比較小眾,剛開始接觸 React 學習的朋友可能并不熟悉他。不過對于 React 頂尖高手而言,這是非常重要的 Hook,他能讓我們對 React 的使用變得更加得心應手。應對更多更復雜的場景。

一、useRef

學習 useImperativeHandle,得從 useRef 說起。我們前面已經學習過了 useRef,它能夠結合元素組件的 ref 屬性幫我們拿到該元素組件對應的真實 DOM。

例如,我想要拿到一個 input 元素的真實 DOM 對象,并調用 input 的 .focus() 方法,讓 input 獲得焦點。

import {useRef} from "react";

export default function Demo() {
  const inputRef = useRef<HTMLInputElement>(null);

  const focusTextInput = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  }

  return (
    <>
      <input type="text" ref={inputRef} />
      <button onClick={focusTextInput}>
        點擊我讓input組件獲得焦點
      </button>
    </>
  );
}

每一個 React 提供的元素組件,都具備 ref 屬性。在上面的章節中我們可以知道,當我們拿到了元素的原生 DOM 對象之后,就可以脫離 React 的開發思路,從而應對更多更復雜的場景。

那么問題就來了,原生組件有自己的 ref 屬性,那么自定義組件呢?當然是沒有的,因此我們得自己想辦法處理。

二、forwardRef

forwardRef 能夠在我們自定義組件時,把內部組件的 ref 屬性傳遞給父組件。

它接受我們自定義的組件作為參數,并返回一個新的組件。新組件具備我們自定義組件的全部能力,并得到一個 ref 屬性,父組件通過 useRef 獲取到的內容與內部組件的 ref 完全一致。

我們來看一個案例。

現在我們要實現如下效果,當點擊 Edit 按鈕時,輸入框自動獲得焦點。

我們知道,在 DOM 中,只要得到 input 對象,然后就可以調用 .focus() 方法來實現目標。現在我們要封裝一個自定義的 MyInput 組件,他具備 input 同樣的能力,同時,我們還要封裝一個標題進去。

<label>Enter your name</label>
<input />

我們的代碼如下:

import {forwardRef, LegacyRef} from 'react'

type MyInputProps = React.InputHTMLAttributes<HTMLInputElement> & {
  label: string
}

function MyInput(props: MyInputProps, ref: LegacyRef<HTMLInputElement>) {
  const {label, ...other} = props

  return (
    <label>
      {label}
      <input {...other} ref={ref} />
    </label>
  )
}

export default forwardRef(MyInput)

MyInput 在聲明時要傳入兩個參數,一個 props,一個 ref。通過展開運算符,我們能夠確保 MyInput 支持 input 所有的屬性。

封裝好之后,我們就可以在點擊實踐中,通過 ref 得到的引用去調用 .focus() 達到 input 獲取焦點的目標。

import { useRef } from 'react'
import MyInput from './MyInput'

export default function ImperativeHandle() {
  const ref = useRef<any>(null)

  function handleClick() {
    ref.current?.focus()
  }

  return (
    <form>
      <MyInput 
        label='Enter your name:' 
        ref={ref} 
      />
      <button type='button' onClick={handleClick}>Edit</button>
    </form>
  )
}

三、useImperativeHandle

在實踐中,很多時候,我們并不想通過 ref 去獲取子組件內部的某個元素組件的真實 DOM 對象。而是希望父組件能夠調用子組件內部的某些方法

但是在 React 中,又無法直接 new 一個子組件的實例,像面向對象那樣通過子組件實例去調用子組件的方法。

因此,React 提供了一個 hook,useImperativeHandle,讓我們能夠重寫子組件內部 ref 對應的引用,從而達到在父組件中,調用子組件內部方法的目的

例如,上面的 MyInput 組件,我們可以修改代碼為:

import {forwardRef, useImperativeHandle, useRef} from 'react'

type MyInputProps = React.InputHTMLAttributes<HTMLInputElement> & {
  label: string
}

function MyInput(props: MyInputProps, ref: any) {
  const {label, ...other} = props
  const inputRef = useRef<any>(null)

  useImperativeHandle(ref, () => {
    return {
      focus() {
        inputRef.current.focus()
      }
    }
  }, [])

  return (
    <label>
      {label}
      <input {...other} ref={inputRef} />
    </label>
  )
}

export default forwardRef(MyInput)
useImperativeHandle(
  ref, 
  createHandle, 
  dependencies?
)

useImperativeHandle 接收三個參數,分別是

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

useImperativeHandle 執行本身返回 undefined。

四、官方案例

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

現在,我們結合前面的知識來分析一下這個案例應該如何實現。

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

<>
  <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,并最終再次透傳給頁面組件。

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

import { forwardRef, useRef, useImperativeHandle } from 'react';

const CommentList = forwardRef(function CommentList(props, 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 的代碼為。

import { forwardRef, useRef, useImperativeHandle } from 'react';

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

export default AddComment;

Post 要把他們整合起來。

import { forwardRef, useRef, useImperativeHandle } from 'react';
import CommentList from './CommentList.js';
import AddComment from './AddComment.js';

const Post = forwardRef((props, 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} />
    </>
  );
});

export default Post;

這樣,我們整個案例的代碼就寫完了。useRef、useImprativeHandle、forwardRef 一起配合幫助我們完成了這個功能。

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

2013-03-18 09:30:14

大數據IT

2020-05-29 10:18:58

python開發代碼

2023-12-20 14:48:26

2024-01-16 08:43:51

React底層機制Hook

2024-02-05 21:48:25

VueReactHooks

2018-05-25 15:10:14

360手機衛士

2011-05-26 10:04:30

程序員

2009-07-16 13:51:43

2018-03-15 09:07:37

手機垃圾文件清理

2022-04-18 17:28:14

React前端

2024-01-25 09:04:25

2024-02-26 12:10:37

2022-04-08 10:15:29

VueReacHooks

2024-02-01 09:05:30

ContextReact性能優化

2011-05-16 16:59:41

SEO

2009-04-15 10:49:01

木馬釋放器卡巴斯基

2023-11-09 16:20:32

Vue.jsReact前端

2019-11-07 21:41:21

AndroidiOS不同

2024-12-06 08:00:51

2009-12-29 15:32:01

架構師
點贊
收藏

51CTO技術棧公眾號

9191国语精品高清在线| 蜜桃视频m3u8在线观看| 久久精品国产99国产精品| 久久手机精品视频| 97人妻精品一区二区三区免费 | a片在线免费观看| 亚洲草久电影| 日韩av在线一区二区| 日本888xxxx| 日本乱理伦在线| 久久你懂得1024| 91久久国产婷婷一区二区| 久久久久无码国产精品| 国产成人黄色| 精品国产一区二区三区不卡 | 激情五月五月婷婷| 刘玥91精选国产在线观看| 日韩和欧美的一区| 久久五月天综合| 91视频在线网站| 亚洲精品黑牛一区二区三区| 色94色欧美sute亚洲线路二 | 老司机午夜精品视频| 欧美成人精品在线| 在线看片中文字幕| 久久精品66| 欧美一区二区三区影视| 久久婷婷国产91天堂综合精品| 黑人玩欧美人三根一起进| 中文字幕av不卡| 玖玖玖精品中文字幕| 亚洲av无码乱码国产精品久久| 免费看黄色91| 欧美怡红院视频一区二区三区| 欧美另类videoxo高潮| 国产精品嫩草影院在线看| 亚洲白拍色综合图区| 一区二区三区人妻| 中文字幕综合| 欧美天天综合网| 日韩欧美xxxx| 涩涩av在线| 午夜私人影院久久久久| 国产精品国三级国产av| 日韩伦理在线电影| 中文字幕国产精品一区二区| 欧美日韩在线精品| 天堂中文在线观看视频| 丰满岳乱妇一区二区三区| 亚洲一区国产精品| 国产喷水福利在线视频| 精彩视频一区二区| 成人免费网站在线| 国产一区二区三区四区视频| 奇米777欧美一区二区| 日本欧美黄网站| 久久久久久久久黄色| 亚洲女同在线| 国产精品av在线| 国产99久久久久久免费看| 视频一区二区不卡| 国产精品高潮粉嫩av| 中文字幕777| 久久成人av少妇免费| 国产一区二区香蕉| 国产情侣自拍小视频| 国产激情一区二区三区| 成人免费看片网站| 男人天堂av网| 91看片淫黄大片一级在线观看| 欧美精品久久| 91美女视频在线| 日韩美女精品在线| 四虎精品欧美一区二区免费| 日本片在线观看| 精品福利一区二区| 久久久久久久久久久久久国产精品| 小黄鸭精品aⅴ导航网站入口| 色狠狠综合天天综合综合| 人人爽人人av| 国产精品成人3p一区二区三区| 欧美一级久久久| 毛茸茸free性熟hd| 免费电影一区二区三区| 一色桃子一区二区| 欧美做爰爽爽爽爽爽爽| 亚洲高清激情| 国产精品久久电影观看| 一区二区三区黄| 成人一区二区三区视频| 麻豆成人小视频| 人人干在线视频| 亚洲大型综合色站| 国产成人手机视频| 欧美9999| 国产亚洲精品久久久久久777| 中文乱码字幕高清一区二区| 亚洲手机视频| 国产精品扒开腿做| www.热久久| 久久精品欧美日韩精品| 国产精品视频一二三四区| 日本在线播放一二三区| 欧美嫩在线观看| 日韩免费高清一区二区| 日韩国产综合| 久久久99国产精品免费| 欧美三级日本三级| 欧美亚洲一级| 99精品欧美一区二区三区| 深夜福利免费在线观看| 亚洲欧洲中文日韩久久av乱码| 国产精品va无码一区二区| 色综合视频一区二区三区日韩| 亚洲精品福利资源站| 男人晚上看的视频| 国产亚洲毛片| av成人观看| 欧洲日本在线| 日韩欧美在线网址 | 国产一区二区伦理| 欧美精品欧美精品| 丁香花高清在线观看完整版| 欧美日韩高清在线| 国产精品亚洲无码| 亚洲国产专区| 99一区二区三区| 国产精品久久久久久福利| 色一区在线观看| 日韩免费高清一区二区| 亚洲无线一线二线三线区别av| 成人美女免费网站视频| 第三区美女视频在线| 婷婷久久综合九色综合伊人色| 亚洲三级在线视频| 国产精品成人一区二区不卡| 国产精品91久久| 水中色av综合| 欧美日韩国产精品专区 | 欧美国产日韩二区| 国产特黄一级片| 国产精品国产三级国产普通话三级 | 欧美亚洲综合网| 精品少妇人妻一区二区黑料社区| 亚洲黄页一区| 国产精品三区www17con| 欧美xxxx做受欧美88bbw| 欧美一级黄色片| 欧美日韩一级大片| 国产剧情一区在线| 天天干天天色天天爽| 粉嫩av国产一区二区三区| 中文字幕亚洲欧美日韩高清| 中文在线免费观看| 中文字幕乱码亚洲精品一区| jizzzz日本| 午夜精品久久久久久久四虎美女版| 国产免费一区视频观看免费| 欧美一级二级三级区| 欧美高清视频www夜色资源网| 中文字幕无码日韩专区免费| 国产精品一区二区久久不卡| www.九色.com| 日韩最新在线| 国产精品视频一区二区高潮| 日本最黄一级片免费在线| 91精品在线免费| 欧美日韩免费做爰视频| 风间由美一区二区三区在线观看| 精品这里只有精品| 精品国产精品| 国产精品亚洲欧美导航| 成人在线免费看黄| 精品福利av导航| 久久青青草视频| 中文字幕在线不卡视频| theporn国产精品| 雨宫琴音一区二区在线| 欧美一区二区高清在线观看| av在线播放一区二区| 久精品免费视频| 国产精品国产高清国产| 欧美午夜精品一区二区蜜桃 | 一级日本在线| 精品国产三级电影在线观看| 日韩一区二区视频在线| 欧美国产激情二区三区| 国内av一区二区| 夜久久久久久| 亚洲成人网上| 亚洲三级av| 国产97在线亚洲| 婷婷免费在线视频| 欧美大片国产精品| 亚洲欧美偷拍一区| 91麻豆视频网站| 亚洲精品久久久中文字幕| 亚洲最新色图| 欧美综合激情| 国产一区一区| 国产成人+综合亚洲+天堂| 求av网址在线观看| 日韩毛片中文字幕| 中文字幕一区二区三区免费看| 亚洲精品国产a久久久久久| 亚洲天堂2024| 国产一区二区三区免费| 精品人妻少妇一区二区| 欧美日韩在线二区| 动漫精品视频| 激情开心成人网| 国语自产偷拍精品视频偷| 大地资源中文在线观看免费版| 91精品中文字幕一区二区三区| 好看的av在线| 亚洲国产视频一区| 一级片久久久久| aaa国产一区| 黄色片免费网址| 久久精品国产亚洲aⅴ| 日韩 欧美 视频| 日韩一区二区在线| 久久riav二区三区| 伊人久久影院| 91在线视频免费| 欧美成a人片在线观看久| 欧美激情乱人伦一区| 欧美日韩欧美| 亚洲天堂网站在线观看视频| 亚洲精品一区二区三区四区| 欧美久久久久久久久久| 瑟瑟视频在线免费观看| 午夜成人在线视频| 欧美 日韩 国产 一区二区三区 | 国产色综合一区二区三区| 国内精品视频| 国产精品免费观看在线| 秋霞伦理一区| 国内精品美女av在线播放| 免费污视频在线| 久久亚洲国产精品| 色的视频在线免费看| 国产亚洲综合久久| 国产二区视频在线观看| 亚洲男人7777| 三级视频在线| 亚洲色图国产精品| 青青久在线视频| 亚洲精品美女免费| 日本成人动漫在线观看| 亚洲精品在线观看网站| 国产浮力第一页| 日韩一区二区在线观看| 国产精品美女一区| 91精品在线麻豆| 99久久精品国产一区色| 欧美一区二区女人| 又骚又黄的视频| 欧美精品一级二级| 国产午夜无码视频在线观看 | 99精品一区二区三区| 男男一级淫片免费播放| 成人小视频免费在线观看| gogo亚洲国模私拍人体| 国产ts人妖一区二区| 潘金莲一级淫片aaaaa| 国产一区二区三区免费观看| 国产精品成人99一区无码| www.激情成人| 极品白嫩丰满美女无套| 久久久另类综合| 波兰性xxxxx极品hd| 亚洲欧洲日本在线| 免费国产羞羞网站美图| 亚洲成人激情自拍| 国产一级在线| 99久久99视频只有精品| 国产欧美韩国高清| 国产精品迅雷| 奇米4444一区二区三区| 亚洲欧洲高清| 亲子乱一区二区三区电影| 在线最新版中文在线| 69av视频在线播放| av激情成人网| 免费在线欧美视频| 国产免费黄色一级片| 亚洲一级电影| av无码精品一区二区三区| 丝袜亚洲另类欧美综合| 午夜精品在线免费观看| 午夜在线a亚洲v天堂网2018| 天堂在线资源视频| 久久精品国产77777蜜臀| 日韩欧美理论片| 精品无码三级在线观看视频| 欧美日韩一区二区区| 99在线精品免费| 国产福利在线导航| 五月天亚洲精品| 一区二区三区麻豆| 欧美一区二区久久| 黄色的视频在线免费观看| 最好看的2019年中文视频| 国产激情小视频在线| 97在线免费视频| 国产日韩一区二区三免费高清| 国产美女99p| 日本一区二区高清不卡| 中国成人在线视频| 精品91视频| 亚洲怡红院在线| 91网站最新网址| 午夜精品福利在线视频| 欧美亚洲高清一区| 国 产 黄 色 大 片| 亚洲欧美色婷婷| 丁香花在线电影| 91精品国产综合久久久久久蜜臀| 国内精品麻豆美女在线播放视频| 日本在线观看一区| 在线免费高清一区二区三区| 制服丝袜综合网| 99国内精品久久| 国产主播在线播放| 精品1区2区3区| 香蕉视频网站在线| 日日噜噜噜夜夜爽亚洲精品| 成人免费av电影| 国产精品国产一区二区| 色综合狠狠操| 狠狠躁狠狠躁视频专区| 91丝袜呻吟高潮美腿白嫩在线观看| 久久精品一区二区三区四区五区| 狠狠躁夜夜躁久久躁别揉| 国内精品久久久久久久久久| 色婷婷av一区二区三区久久| 2020国产在线| 国产私拍一区| 欧美日一区二区在线观看| 伊人网在线综合| 国产精品久久影院| 亚洲 日本 欧美 中文幕| 亚洲成人av片| 高潮在线视频| 国产精品国色综合久久| 自拍偷拍欧美专区| 中文字幕55页| 亚洲女同ⅹxx女同tv| 国产一区二区三区四区视频| 久久视频这里只有精品| 国产精品天堂蜜av在线播放| 欧美在线视频一区二区三区| 久久综合中文| 亚洲天堂视频一区| 色综合久久中文综合久久97| 日本免费一区视频| 久久久久国产精品www| 亚洲不卡在线| 在线视频不卡一区二区三区| 狠狠色丁香久久婷婷综合_中 | 亚洲网中文字幕| 中文字幕在线视频一区| 亚洲视频在线观看免费视频| 中文国产成人精品久久一| 日韩一区二区三区四区五区| 亚洲精品乱码视频| 日本亚洲天堂网| 一区二区国产精品精华液| 在线播放亚洲一区| av免费在线观看网址| 国产欧美精品一区二区三区| 99日韩精品| 国产熟妇久久777777| 欧美日韩国产免费| 快射av在线播放一区| 51国偷自产一区二区三区 | 向日葵视频成人app网址| 日本一区免费看| 奇米精品一区二区三区在线观看| 成人自拍小视频| 欧美大胆一级视频| 免费看男女www网站入口在线 | 又黄又爽又色的视频| 亚洲一区二区av在线| 日韩中文字幕影院| 日本精品免费观看| 91精品国产自产在线观看永久∴| 在线成人精品视频| 精品国产乱码久久久久久婷婷| 国产黄色在线播放| 亚洲a∨日韩av高清在线观看| 狠狠综合久久| 91社区视频在线观看| 91精品国产色综合久久不卡蜜臀| 国产网红女主播精品视频| 亚洲精品一品区二品区三品区| 国产老肥熟一区二区三区| 特级毛片www| 欧美激情综合色综合啪啪五月|