useRef使用總結

下圖是useRef的demo效果圖,經過「一個父組件嵌套一個子組」件來總結一些知識點。react

demo

父組件

知識點總結

  1. useRef是一個方法,且useRef返回一個可變的ref對象(對象!!!)
  2. initialValue被賦值給其返回值的.current對象
  3. 能夠保存任何類型的值:dom、對象等任何可辨值
  4. ref對象與自建一個{current:‘’}對象的區別是:useRef會在每次渲染時返回同一個ref對象,即返回的ref對象在組件的整個生命週期內保持不變。自建對象每次渲染時都創建一個新的。
  5. ref對象的值發生改變以後,不會觸發組件從新渲染。有一個竅門,把它的改邊動做放到useState()以前。
  6. 本質上,useRef就是一個其.current屬性保存着一個可變值「盒子」。目前我用到的是pageRef和sortRef分別用來保存分頁信息和排序信息。

代碼示例

import React, {
  useRef,
  useEffect,
  useImperativeHandle,
  forwardRef,
} from "react";

const RefDemo = () => {
  const domRef = useRef(1);
  const childRef = useRef(null);
  useEffect(() => {
    console.log("ref:deom-init", domRef, domRef.current);
    console.log("ref:child-init", childRef, childRef.current);
  });
  const showChild = () => {
    console.log("ref:child", childRef, childRef.current);
    childRef.current.say();
  };
  return (
    <div style={{ margin: "100px", border: "2px dashed", padding: "20px" }}>
      <h2>這是外層組件</h2>
      <div
        onClick={() => {
          console.log("ref:deom", domRef, domRef.current);
          domRef.current.focus();
          domRef.current.value = 'hh';
        }}
      >
       <label>這是一個dom節點</label><input ref={domRef} />
      </div>
      <br />
      <p onClick={showChild} style={{ marginTop: "20px" }}>
        這是子組件
      </p>
      <div style={{ border: "1px solid", padding: "10px" }}>
        <Child ref={childRef} />
      </div>
    </div>
  );
};
export default RefDemo;
複製代碼

子組件

知識點總結

  1. useImperativeHandle(ref,createHandle,[deps])能夠自定義暴露給父組件的實例值。若是不使用,父組件的ref(chidlRef)訪問不到任何值(childRef.current==null)
  2. useImperativeHandle應該與forwradRef搭配使用
  3. React.forwardRef會建立一個React組件,這個組件可以將其接受的ref屬性轉發到其組件樹下的另外一個組件中。
  4. React.forward接受渲染函數做爲參數,React將使用prop和ref做爲參數來調用此函數。

代碼示例

const Child = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    say: sayHello,
  }));
  const sayHello = () => {
    alert("hello,我是子組件");
  };
  return <h3>子組件</h3>;
});


等同於 =>

const ChildComponent = (props, ref) => {
  useImperativeHandle(ref, () => ({
    say: sayHello,
  }));
  const sayHello = () => {
    alert("hello,我是子組件");
  };
  return <h3>子組件</h3>;
};
const Child = forwardRef(ChildComponent);
複製代碼
相關文章
相關標籤/搜索