beecomci / today_i_learned

0 stars 0 forks source link

[React-Basic-Hooks] 8. Handle DOM in React (ref) #12

Open beecomci opened 3 years ago

beecomci commented 3 years ago

๐Ÿ“ useRef ์‚ฌ์šฉ์€ ์–ธ์ œ?

DOM์— ref ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹์€ ์˜ˆ

๊ทธ ์™ธ์—๋Š” ๋˜๋„๋ก ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

๐Ÿ’ก์„ ์–ธ์ (declartive)์œผ๋กœ ์ƒ๊ฐํ•˜๊ธฐ => Dialog component์˜ open(), close() ํ•จ์ˆ˜๋ฅผ ๋…ธ์ถœํ•˜๊ธฐ ๋ณด๋‹ค๋Š”(๋ช…๋ นํ˜•) isOpen ๊ฐ’(์ƒํƒœ๊ฐ’)์„ ์ „๋‹ฌํ•˜์—ฌ ์ œ์–ดํ•˜๋„๋ก ํ•œ๋‹ค. ์ƒํƒœ์— ๋งž๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ทธ๋ฆฌ๋„๋ก React์—๊ฒŒ ์œ„์ž„, Dialog ๋‚ด์—์„œ๋Š” isOpen์˜ ์ƒํƒœ๊ฐ’์— ๋งž๋Š” ํ™”๋ฉด ์ •์˜๊ฐ€ ์ž˜ ๋˜์–ด ์žˆ์œผ๋ฉด Dialog๊ฐ€ ๋ฐ›๋Š” props(isOpen)์œผ๋กœ ์ œ์–ด๋จ

DOM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์‹œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ?

@07-refs/dom

import { useRef } from 'react';

const TextInput = () => {
  // DOM ์ ‘๊ทผ์‹œ ref ์‚ฌ์šฉ
  const textInputRef = useRef(null);
  const focusInput = () => {
    // ์ ‘๊ทผ์‹œ current๋กœ ์ ‘๊ทผํ•˜๋ฉด ์‹ค์ œ dom ์ ‘๊ทผ
    textInputRef.current.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={textInputRef} // React๊ฐ€ ์‹ค์ œ DOM render ํ›„ reference๋ฅผ ๋ถ™์—ฌ์คŒ
      />
      <button onClick={focusInput}>
        Focus
      </button>
    </div>
  );
}

forwardRef

@07-refs/forward

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

function AutoFocusTextInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focusInput();
  }, []); // mount ๋˜์—ˆ์„ ๋•Œ 1๋ฒˆ๋งŒ ์‹คํ–‰

  return <ForwaredTextInput ref={inputRef} />;
}

// forwardRef๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ref ์ „๋‹ฌ๋ฐ›๊ธฐ ๊ฐ€๋Šฅ
function TextInput(props, ref) {
  const textInput = useRef(null);

  const focusInput = () => {
    textInput.current.focus();
  }

  // focuseInput ํ•จ์ˆ˜๋ฅผ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•˜๊ฒ ๋”ฐ
  useImperativeHandle(ref, () => ({ focusInput }))

  return (
    <div>
      <input
        type="text"
        ref={textInput}
      />
      <button onClick={focusInput}>
        Focus
      </button>
    </div>
  );
}

// forwardRef๋กœ ๊ฐ์‹ผ TextInput ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ€๋ชจ ForwaredTextInput์— ์ „๋‹ฌ
// ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์‹œ ref ์ฃผ์ž…
const ForwaredTextInput = forwardRef(TextInput)

export default AutoFocusTextInput;

// ์ง€๊ธˆ์ฒ˜๋Ÿผ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ถˆํŽธํ•˜๊ฒŒ ์ œ์–ดํ•˜์ง€ ์•Š๊ณ  TextInput์˜ props์— isAutoFocus flag ์ „๋‹ฌ๋กœ ๋‚ด๋ถ€์—์„œ flag ์ƒํƒœ๊ฐ’์— ๋”ฐ๋ฅธ render๋ฅผ ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๋” ์ถ”์ฒœ