(React) forwardRef

soosoorim·2024년 5월 16일
0

forwardRef
Ref는 Props로 전달할 수 없는 객체 (24.04월 전달할 수 있다고 바뀜!)
Ref를 자식컴포넌트로 전달하려면, 특수한 형태의 컴포넌트가 필요.
=> forwardRef Component

Ref / forwardRef로 Modal을 만들어보자!

  • AlertModal을 열고 닫기 위해서는 open, onClose props를 전달해야 함.
  • Dialog modal은 dialog.showModal(), dialog.close() 로 제어해야함.
  • Props로는 기능 제어가 불가능!
  • 함수로 제어 O

<AlertModal.js>

import { forwardRef } from "react";

/**
 * export: AlertModal 컴포넌트(함수)/변수/상수 등등을 외부로 공개하기 위한 방법
 * import: { AlertModal } from "./path";
 *
 * export default : AlertModal 컴포넌트(함수)/변수/상수 등등을 외부로 공개하기 위한 방법
 *      AlertModal.js 파일을 import 했을 때, 대표 컴포넌트(함수)/변수/상수를 공개하는 방법
 * 하나의 js 파일에 하나의 export default만 작성.
 * 한 파일 내에서 export default를 여러번 작성 X
 * import AlertModal, { OtherComponent } from "./path";
 */
// export default function AlertModal({ children }) {
const AlertModal = forwardRef(({ onClose, children }, ref) => {
  return (
    <dialog className="modal" ref={ref}>
      <div className="modal-body">
        <section className="modal-close-button" onClick={onClose}>
          X
        </section>
        {children}
      </div>
    </dialog>
  );
});

export default AlertModal;

<Input.js>

import { forwardRef } from "react";

// export default function Input({ id, type, title }) {
const Input = forwardRef(({ id, type, title }, ref) => {
  return (
    <>
      <label htmlFor={id}>{title}</label>
      <input type={type} id={id} ref={ref} />
    </>
  );
});
// }

export default Input;

<RefComponent.js>

import { useRef, useState } from "react";
import AlertModal from "./modal/AlertModal.js";
import Input from "./ui/Input.js";

export function RefComponent() {
  const alertModalRef = useRef();

  const [item, setItem] = useState([]);
  const itemRef = useRef();

  const onClickHandler = () => {
    const itemValue = itemRef.current.value;

    if (itemValue === "") {
      console.log(alertModalRef.current);
      alertModalRef.current.showModal();
      itemRef.current.focus();
      return;
    }

    setItem((prevState) => [itemValue, ...prevState]);

    itemRef.current.value = "";
    itemRef.current.focus();
  };

  const onCloseModalHandler = () => {
    alertModalRef.current.close();
  };

  return (
    <div className="main-container">
      <Input id="text" type="text" title="Text" ref={itemRef} />
      <button onClick={onClickHandler}>Save</button>
      <hr />
      <ul>
        {item.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>

      <AlertModal onClose={onCloseModalHandler} ref={alertModalRef}>
        <div>
          <h3>텍스트를 입력하세요!</h3>
        </div>
      </AlertModal>
    </div>
  );
}

<App.js>

import { RefComponent } from "./components/RefComponent";

function App() {
  return <RefComponent />;
}

export default App;

0개의 댓글

관련 채용 정보