<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          useImperativeHandle應(yīng)用及原理

          共 2291字,需瀏覽 5分鐘

           ·

          2022-05-14 06:38

          OOKS了吧:useState,?useEffect,?useContext,?useMemo。但我當(dāng)?shù)谝淮慰吹?code style="box-sizing: border-box;font-family: var(--bs-font-monospace);font-size: 0.875em;direction: ltr;unicode-bidi: bidi-override;color: rgb(214, 51, 132);overflow-wrap: break-word;">useImperativeHandle時(shí),一臉懵逼(這是什么鬼東西~~~)。

          一、是什么?

          React官網(wǎng)對(duì)useImperativeHandle介紹也比較簡短。總結(jié)一句話就是:子組件利用useImperativeHandle可以讓父組件輸出任意數(shù)據(jù)

          // FancyInput組件作為子組件
          const FancyInput = React.forwardRef(function FancyInput(props, ref) {
          const inputRef = useRef();

          // 命令式的給`ref.current`賦值個(gè)對(duì)象
          useImperativeHandle(ref, () => ({
          focus: () => {
          inputRef.current.focus()
          }
          }));

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

          // Example組件作為父組件
          function Example() {
          const fancyInputRef = useRef()

          const focus = () => {
          fancyInputRef.current.focus()
          }

          return (
          <>
          <FancyInput ref={fancyInputRef} />

          )
          }

          二、怎么用?

          2.1 語法

          useImperativeHandle(ref, createHandle, [deps])
          1. ref
            需要被賦值的ref對(duì)象。

          2. createHandle
            createHandle函數(shù)的返回值作為ref.current的值。

          3. [deps]
            依賴數(shù)組,依賴發(fā)生變化會(huì)重新執(zhí)行createHandle函數(shù)。

          2.2 進(jìn)階:什么時(shí)候執(zhí)行createHandle函數(shù)?

          測(cè)試發(fā)現(xiàn)和useLayoutEffect執(zhí)行時(shí)機(jī)一致。
          修改下組件FancyInput內(nèi)容:

          const FancyInput = React.forwardRef(function FancyInput(props, ref) {
          const inputRef = useRef();
          console.log('render 1')

          useLayoutEffect(() => {
          console.log('useEffect1', ref)
          })

          useImperativeHandle(ref, function() {
          debugger
          console.log('useImperativeHandle')
          return {
          focus: () => {
          inputRef.current.focus();
          }
          }
          })

          useLayoutEffect(() => {
          console.log('useEffect2', ref);
          })

          console.log('render 2')
          return <input ref={inputRef} placeholder="FancyInput"/>;
          })


          看看控制臺(tái)輸出發(fā)現(xiàn)createHandle函數(shù)的執(zhí)行時(shí)機(jī)和useLayoutEffect一致,這樣就保證了在任意位置的useEffect里都能拿到最新的ref.current的值

          注意:執(zhí)行createHandle函數(shù)的還有個(gè)前提條件,即useImperativeHandle的第一個(gè)實(shí)參ref必須有值(否則執(zhí)行createHandle函數(shù)也沒意義啊)。

          2.3 應(yīng)用場(chǎng)景

          目前項(xiàng)目已經(jīng)有多處使用場(chǎng)景了,主要是解決父組件獲取子組件的數(shù)據(jù)或者調(diào)用子組件的里聲明的函數(shù)。
          如formik庫的一處使用:

          React.useImperativeHandle(innerRef, () => formikbag);

          2.4 最佳實(shí)踐

          React官網(wǎng)里給出了幾點(diǎn)使用建議:

          1. 盡量避免命令式地給ref.current賦值,盡量采用聲明式的(即讓React內(nèi)部處理);

          2. forwardRef搭配使用
            這個(gè)不一定,比如上面fomik庫就沒有這樣做。

          三、原理

          先回顧下我們之前是如何使用ref的:

          1. 期初利用ref訪問子組件的實(shí)例或則DOM元素;

          2. 后來useRef出現(xiàn)了,我們?cè)诤瘮?shù)組件里利用useRef還可以存儲(chǔ)一些類似成員變量的數(shù)據(jù)。

          再回顧下React如何處理聲明式ref的:

          React will assign the current property with the DOM element when the component mounts, and assign it back to null when it unmounts.

          通過之前的知識(shí)我們可以達(dá)成幾點(diǎn)共識(shí):

          1. ref.current賦值是個(gè)副作用,所以一般在Did函數(shù)或者事件處理函數(shù)里給ref.current賦值;

          2. 組件在卸載時(shí)要清理ref.current的值。

          本質(zhì)上useImperativeHandle就是在幫我們做這些事情。

          四、為什么需要useImperativeHandle

          我們都知道父組件可以利用ref可以訪問子組件實(shí)例或者DOM元素,這其實(shí)相當(dāng)于子組件向父組件輸出本身實(shí)例或者DOM元素。而利用useImperativeHandle子組件可以向父組件輸出任意數(shù)據(jù)。

          瀏覽 75
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久操免费视频 | a篇,乱伦,欧美,国产 | 麻豆出品必是精品(3) | 黄色日本免费看 | 日韩欧美网站 |