useRef 和 forwardRef

為什麼要使用 useRefforwardRef

useRef

  1. 可以維持元件的狀態,並且不會觸發重新渲染。
  2. 可以用來控制DOM元素,例如:focus、scroll、play、pause等。
    程式碼範例如下:
function MyComponent() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus(); // 自動聚焦
  }, []);

  return <input ref=&#123;inputRef&#125; />;
&#125;

forwardRef

  1. 可以將ref傳遞到子元件。
  2. 如果不使用forwardRef,React會報錯
    程式碼範例如下:
// 定義一個 FancyButton 組件,使用 forwardRef 將 ref 傳遞下去
const FancyButton = forwardRef((props, ref) => (
  <button ref=&#123;ref&#125; className="FancyButton">
    &#123;props.children&#125;
  </button>
));

function App() &#123;
  const buttonRef = useRef(null);

  const handleClick = () => &#123;
    if (buttonRef.current) &#123;
      buttonRef.current.focus(); // 使用 ref 來聚焦按鈕
    &#125;
  &#125;;

  return (
    <div>
      <FancyButton ref=&#123;buttonRef&#125;>Click me!</FancyButton>
      <button onClick=&#123;handleClick&#125;>Focus Fancy Button</button>
    </div>
  );
&#125;

同場加映:useImperativeHandle

目的是限制暴露的方法給父元件來做使用


// 定義一個自定義輸入框組件,使用 forwardRef 傳遞 ref
const CustomInput = forwardRef((props, ref) => &#123;
  const inputRef = useRef();

  // 使用 useImperativeHandle 來暴露 focus 方法給父組件
  useImperativeHandle(ref, () => (&#123;
    focus: () => &#123;
      inputRef.current.focus();
    &#125;
  &#125;));

  return <input ref=&#123;inputRef&#125; &#123;...props&#125; />;
&#125;);

function ParentComponent() &#123;
  const inputRef = useRef();

  const handleClick = () => &#123;
    inputRef.current.focus(); // 使用 ref 來聚焦輸入框
  &#125;;

  return (
    <div>
      <CustomInput ref=&#123;inputRef&#125; placeholder="Click the button to focus" />
      <button onClick=&#123;handleClick&#125;>Focus Input</button>
    </div>
  );
&#125;

說明:

  1. 自定義輸入框組件 CustomInput:使用 forwardRef 來接收 ref 並將其傳遞給內部的 input 元素。
  2. 使用 useImperativeHandle:這允許我們在父組件中自定義暴露的方法(如 focus)。
  3. 父組件 ParentComponent:使用 useRef 來創建 ref,並通過按鈕點擊觸發輸入框的聚焦。

相關文章

React-Hook-useContext
React Hook

2024/03/06

React Hook-useMemo
React Hook

2024/01/11

Day 30 遲來的完賽
React JavaScript

2024/01/09