We want to hear from you!Take our 2021 Community Survey!
Support Ukraine ๐Ÿ‡บ๐Ÿ‡ฆ Help Provide Humanitarian Aid to Ukraine.

Ref์™€ DOM

Ref๋Š” render ๋ฉ”์„œ๋“œ์—์„œ ์ƒ์„ฑ๋œ DOM ๋…ธ๋“œ๋‚˜ React ์—˜๋ฆฌ๋จผํŠธ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ React์˜ ๋ฐ์ดํ„ฐ ํ”Œ๋กœ์šฐ์—์„œ props๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์‹๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค. ์ž์‹์„ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ์ƒˆ๋กœ์šด props๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ์ž์‹์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ์ผ๋ฐ˜์ ์ธ ๋ฐ์ดํ„ฐ ํ”Œ๋กœ์šฐ์—์„œ ๋ฒ—์–ด๋‚˜ ์ง์ ‘์ ์œผ๋กœ ์ž์‹์„ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ๊ฐ€๋”์”ฉ ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜์ •ํ•  ์ž์‹์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค์ผ ์ˆ˜๋„ ์žˆ๊ณ , DOM ์—˜๋ฆฌ๋จผํŠธ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘๋ฅผ ์œ„ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Ref๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ

Ref์˜ ๋ฐ”๋žŒ์งํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํฌ์ปค์Šค, ํ…์ŠคํŠธ ์„ ํƒ์˜์—ญ, ํ˜น์€ ๋ฏธ๋””์–ด์˜ ์žฌ์ƒ์„ ๊ด€๋ฆฌํ•  ๋•Œ.
  • ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ง์ ‘์ ์œผ๋กœ ์‹คํ–‰์‹œํ‚ฌ ๋•Œ.
  • ์„œ๋“œ ํŒŒํ‹ฐ DOM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ React์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ๋•Œ.

์„ ์–ธ์ ์œผ๋กœ ํ•ด๊ฒฐ๋  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์—์„œ๋Š” ref ์‚ฌ์šฉ์„ ์ง€์–‘ํ•˜์„ธ์š”.

์˜ˆ๋ฅผ ๋“ค์–ด, Dialog ์ปดํฌ๋„ŒํŠธ์—์„œ open()๊ณผ close() ๋ฉ”์„œ๋“œ๋ฅผ ๋‘๋Š” ๋Œ€์‹ , isOpen์ด๋ผ๋Š” prop์„ ๋„˜๊ฒจ์ฃผ์„ธ์š”.

Ref๋ฅผ ๋‚จ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”

ref๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— โ€œ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๊ฒŒโ€ ํ•  ๋•Œ ์‚ฌ์šฉ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ๋•Œ๋Š” ์ž ์‹œ ๋ฉˆ์ถ”๊ณ  ์–ด๋Š ์ปดํฌ๋„ŒํŠธ ๊ณ„์ธต์—์„œ ์ƒํƒœ๋ฅผ ์†Œ์œ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์‹ ์ค‘ํ•˜๊ฒŒ ์ƒ๊ฐํ•ด๋ณด์„ธ์š”. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, ์ƒํƒœ๋ฅผ ์†Œ์œ ํ•ด์•ผ ํ•˜๋Š” ์ ์ ˆํ•œ ์žฅ์†Œ๊ฐ€ ๋” ๋†’์€ ๊ณ„์ธต์ด๋ผ๋Š” ๊ฒฐ๋ก ์ด ๋‚  ๊ฒ๋‹ˆ๋‹ค. ์ƒํƒœ๋ฅผ ์ƒ์œ„ ๊ณ„์ธต์œผ๋กœ ์˜ฌ๋ฆฌ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์˜ˆ์‹œ๋Š” ์ƒํƒœ ๋Œ์–ด์˜ฌ๋ฆฌ๊ธฐ ๊ฐ€์ด๋“œ์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์œผ์‹ญ๋‹ˆ๋‹ค.

์ฃผ์˜

์•„๋ž˜์— ์žˆ๋Š” ์˜ˆ์‹œ๋Š” React 16.3 ์—์„œ ์ถ”๊ฐ€๋œ React.createRef() API๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ „ ๋ฒ„์ „์˜ React๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ณ„์‹ ๋‹ค๋ฉด, ์ฝœ๋ฐฑ ref๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•˜์‹œ๋Š” ํŽธ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Ref ์ƒ์„ฑํ•˜๊ธฐ

Ref๋Š” React.createRef()๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋˜๊ณ  ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ํ†ตํ•ด React ์—˜๋ฆฌ๋จผํŠธ์— ๋ถ€์ฐฉ๋ฉ๋‹ˆ๋‹ค. ๋ณดํ†ต, ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ Ref๋ฅผ ํ”„๋กœํผํ‹ฐ๋กœ์„œ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ทธ๋Ÿผ์œผ๋กœ์„œ ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค์˜ ์–ด๋Š ๊ณณ์—์„œ๋„ Ref์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();  }
  render() {
    return <div ref={this.myRef} />;  }
}

Ref์— ์ ‘๊ทผํ•˜๊ธฐ

render ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ ref๊ฐ€ ์—˜๋ฆฌ๋จผํŠธ์—๊ฒŒ ์ „๋‹ฌ๋˜์—ˆ์„ ๋•Œ, ๊ทธ ๋…ธ๋“œ๋ฅผ ํ–ฅํ•œ ์ฐธ์กฐ๋Š” ref์˜ current ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์— ๋‹ด๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

const node = this.myRef.current;

ref์˜ ๊ฐ’์€ ๋…ธ๋“œ์˜ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

  • ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๊ฐ€ HTML ์—˜๋ฆฌ๋จผํŠธ์— ์“ฐ์˜€๋‹ค๋ฉด, ์ƒ์„ฑ์ž์—์„œ React.createRef()๋กœ ์ƒ์„ฑ๋œ ref๋Š” ์ž์‹ ์„ ์ „๋‹ฌ๋ฐ›์€ DOM ์—˜๋ฆฌ๋จผํŠธ๋ฅผ current ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์œผ๋กœ์„œ ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๊ฐ€ ์ปค์Šคํ…€ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์— ์“ฐ์˜€๋‹ค๋ฉด, ref ๊ฐ์ฒด๋Š” ๋งˆ์šดํŠธ๋œ ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ current ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์œผ๋กœ์„œ ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์— ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์˜ ์˜ˆ์‹œ๋“ค์€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ์ฐจ์ด์ ๋“ค์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

DOM ์—˜๋ฆฌ๋จผํŠธ์— Ref ์‚ฌ์šฉํ•˜๊ธฐ

์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” DOM ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ref๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // textInput DOM ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ref๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    this.textInput = React.createRef();    this.focusTextInput = this.focusTextInput.bind(this);
  }

  focusTextInput() {
    // DOM API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…์‹œ์ ์œผ๋กœ text ํƒ€์ž…์˜ input ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํฌ์ปค์Šคํ•ฉ๋‹ˆ๋‹ค.
    // ์ฃผ์˜: ์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ DOM ๋…ธ๋“œ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด "current" ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    this.textInput.current.focus();  }

  render() {
    // React์—๊ฒŒ ์šฐ๋ฆฌ๊ฐ€ text ํƒ€์ž…์˜ input ์—˜๋ฆฌ๋จผํŠธ๋ฅผ
    // ์šฐ๋ฆฌ๊ฐ€ ์ƒ์„ฑ์ž์—์„œ ์ƒ์„ฑํ•œ `textInput` ref์™€ ์—ฐ๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ์ด์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค.
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ React๋Š” current ํ”„๋กœํผํ‹ฐ์— DOM ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋Œ€์ž…ํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ์˜ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋  ๋•Œ current ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‹ค์‹œ null๋กœ ๋Œ๋ ค ๋†“์Šต๋‹ˆ๋‹ค. ref๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ž‘์—…์€ componentDidMount ๋˜๋Š” componentDidUpdate ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์— ref ์‚ฌ์šฉํ•˜๊ธฐ

์•„๋ž˜์— ์žˆ๋Š” CustomTextInput ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งˆ์šดํŠธ ๋œ ์ดํ›„์— ์ฆ‰์‹œ ํด๋ฆญ๋˜๋Š” ๊ฑธ ํ‰๋‚ด๋‚ด๊ธฐ ์œ„ํ•ด CustomTextInput ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ์‹ธ๋Š” ๊ฑธ ์›ํ•œ๋‹ค๋ฉด, ref๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CustomTextInput ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•˜๊ณ  ์ง์ ‘ focusTextInput ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();  }

  componentDidMount() {
    this.textInput.current.focusTextInput();  }

  render() {
    return (
      <CustomTextInput ref={this.textInput} />    );
  }
}

์œ„ ์ฝ”๋“œ๋Š” CustomTextInput๊ฐ€ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์ผ ๋•Œ์—๋งŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.

class CustomTextInput extends React.Component {  // ...
}

Ref์™€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ

  • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์— ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
function MyFunctionComponent() {  return <input />;
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();  }
  render() {
    // ์ด ์ฝ”๋“œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    return (
      <MyFunctionComponent ref={this.textInput} />    );
  }
}

ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์— ref๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ ค๋ฉด, forwardRef (๋†’์€ ํ™•๋ฅ ๋กœ useImperativeHandle์™€ ํ•จ๊ป˜)๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋งŒ, DOM ์—˜๋ฆฌ๋จผํŠธ๋‚˜ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ฉ๋‹ˆ๋‹ค.

function CustomTextInput(props) {
  // textInput์€ ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋˜๊ธฐ ์œ„ํ•ด์„œ  // ์ด๊ณณ์—์„œ ์ •์˜๋˜์–ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.  const textInput = useRef(null);

  function handleClick() {    textInput.current.focus();
  }

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

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ DOM ref๋ฅผ ๊ณต๊ฐœํ•˜๊ธฐ

๋ณด๊ธฐ ๋“œ๋ฌธ ๊ฒฝ์šฐ์ง€๋งŒ, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ์— ์ ‘๊ทผํ•˜๋ ค ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ ์ปดํฌ๋„ŒํŠธ์˜ ์บก์Šํ™”๋ฅผ ํŒŒ๊ดดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ ๊ฐ€๋”๊ฐ€๋‹ค ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ๋ฅผ ํฌ์ปค์Šคํ•˜๋Š” ์ผ์ด๋‚˜, ํฌ๊ธฐ ๋˜๋Š” ์œ„์น˜๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ์ผ ๋“ฑ์„ ํ•  ๋•Œ์—๋Š” ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ref๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด ๋ฐฉ๋ฒ•์€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค์˜ DOM ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ์ ์—์„œ, ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์ธ ๊ฒฝ์šฐ์—๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์—์„œ, ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค.

React 16.3 ์ดํ›„ ๋ฒ„์ „์˜ React๋ฅผ ์‚ฌ์šฉํ•˜์‹ ๋‹ค๋ฉด ์œ„์™€ ๊ฐ™์€ ๊ฒฝ์šฐ์—์„œ ref ์ „๋‹ฌํ•˜๊ธฐ(ref forwarding)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. Ref ์ „๋‹ฌํ•˜๊ธฐ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ref๋ฅผ ์ž์‹ ์˜ ref๋กœ์„œ ์™ธ๋ถ€์— ๋…ธ์ถœ์‹œํ‚ค๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ๋ฅผ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ๊ณต๊ฐœํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์˜ˆ์‹œ๋Š” ref ๋„˜๊ฒจ์ฃผ๊ธฐ ๋ฌธ์„œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

React 16.2 ์ด์ „ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜์‹œ๊ฑฐ๋‚˜ ref ์ „๋‹ฌํ•˜๊ธฐ๋ณด๋‹ค ๋” ์œ ์—ฐํ•œ ๋ฐฉ๋ฒ•์„ ์›ํ•œ๋‹ค๋ฉด ์ด๋Ÿฐ ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด DOM ๋…ธ๋“œ๋ฅผ ์™ธ๋ถ€์— ๊ณต๊ฐœํ•˜๋Š” ์ผ์„ ์ง€์–‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค๋งŒ DOM ๋…ธ๋“œ๋ฅผ ์™ธ๋ถ€์— ๊ณต๊ฐœํ•˜๋Š” ์ผ์€ ์œ ์šฉํ•œ ํ•ด๊ฒฐ์ฑ…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ๋ฐฉ๋ฒ•๋“ค์€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ ์ˆ˜์ •์„ ์š”ํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ์ตœํ›„์˜ ๋ฐฉ๋ฒ•์ธ findDOMNode()๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ findDOMNode()๋Š” ์ข‹์ง€ ๋ชปํ•œ ๋ฐฉ๋ฒ•์ผ ๋ฟ๋”๋Ÿฌ StrictMode์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ ref

React๋Š” ref๊ฐ€ ์„ค์ •๋˜๊ณ  ํ•ด์ œ๋˜๋Š” ์ƒํ™ฉ์„ ์„ธ์„ธํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” โ€œ์ฝœ๋ฐฑ refโ€ ์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ref๋ฅผ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ ref๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์— React.createRef()๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ ref๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋Œ€์‹ , ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ „๋‹ฌ๋œ ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ๊ณณ์— ์ €์žฅ๋˜๊ณ  ์ ‘๊ทผ๋  ์ˆ˜ ์žˆ๋Š” React ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค๋‚˜ DOM ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ธ์ž๋กœ์„œ ๋ฐ›์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์˜ ์˜ˆ์‹œ๋Š” DOM ๋…ธ๋“œ์˜ ์ฐธ์กฐ๋ฅผ ์ธ์Šคํ„ด์Šค์˜ ํ”„๋กœํผํ‹ฐ์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ref ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜๋Š” ํ”ํ•œ ํŒจํ„ด์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);

    this.textInput = null;
    this.setTextInputRef = element => {      this.textInput = element;    };
    this.focusTextInput = () => {      // DOM API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ text ํƒ€์ž…์˜ input ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํฌ์ปค์Šคํ•ฉ๋‹ˆ๋‹ค.      if (this.textInput) this.textInput.focus();    };  }

  componentDidMount() {
    // ๋งˆ์šดํŠธ ๋˜์—ˆ์„ ๋•Œ ์ž๋™์œผ๋กœ text ํƒ€์ž…์˜ input ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํฌ์ปค์Šคํ•ฉ๋‹ˆ๋‹ค.
    this.focusTextInput();  }

  render() {
    // text ํƒ€์ž…์˜ input ์—˜๋ฆฌ๋จผํŠธ์˜ ์ฐธ์กฐ๋ฅผ ์ธ์Šคํ„ด์Šค์˜ ํ”„๋กœํผํ‹ฐ
    // (์˜ˆ๋ฅผ ๋“ค์–ด`this.textInput`)์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด `ref` ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    return (
      <div>
        <input
          type="text"
          ref={this.setTextInputRef}        />
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}        />
      </div>
    );
  }
}

์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งˆ์šดํŠธ ๋  ๋•Œ React๋Š” ref ์ฝœ๋ฐฑ์„ DOM ์—˜๋ฆฌ๋จผํŠธ์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค์˜ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋  ๋•Œ, ref ์ฝœ๋ฐฑ์„ null๊ณผ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ref ์ฝœ๋ฐฑ๋“ค์€ componentDidMount ๋˜๋Š” componentDidUpdate๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ ref ๋˜ํ•œ React.createRef()๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ–ˆ์—ˆ๋˜ ๊ฐ์ฒด ref์™€ ๊ฐ™์ด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />    </div>
  );
}

class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
        inputRef={el => this.inputElement = el}      />
    );
  }
}

์œ„์˜ ์˜ˆ์‹œ์—์„œ Parent๋Š” ์ž์‹ ์˜ ์ฝœ๋ฐฑ ref๋ฅผ inputRef prop์œผ๋กœ์„œ CustomTextInput์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  CustomTextInput์€ ์ „๋‹ฌ๋ฐ›์€ ํ•จ์ˆ˜๋ฅผ <input>์—๊ฒŒ ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋กœ์„œ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ Parent์— ์žˆ๋Š” this.inputElement๋Š” CustomTextInput์˜ <input> ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€์‘ํ•˜๋Š” DOM ๋…ธ๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๋ ˆ๊ฑฐ์‹œ API: ๋ฌธ์ž์—ด ref

React๋ฅผ ์ด์ „์— ์‚ฌ์šฉํ•ด ๋ณด์…จ๋‹ค๋ฉด ref ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์˜ ๊ฐ’์ด "textInput" ์ฒ˜๋Ÿผ ๋ฌธ์ž์—ด์ด๊ณ , DOM ๋…ธ๋“œ๋ฅผ this.refs.textInput์™€ ๊ฐ™์ด ์ ‘๊ทผํ•˜๋Š” ๊ตฌ์‹ API๋ฅผ ์•„์‹œ๊ณ  ๊ณ„์‹ค์ง€๋„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด ref๋Š” ๋ช‡๋ช‡ ๋ฌธ์ œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๋ ˆ๊ฑฐ์‹œ๋กœ ์—ฌ๊ฒจ์ง€๋ฉฐ, ์ฐจํ›„ ๋ฐฐํฌ์—์„œ ์‚ญ์ œ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฃผ์˜

ref์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด this.refs.textInput๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ณ„์‹ ๋‹ค๋ฉด, ์ฝœ๋ฐฑ ref์ด๋‚˜ createRef API๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒํ•ด ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ ref์— ๊ด€ํ•œ ์ฃผ์˜์‚ฌํ•ญ

ref ์ฝœ๋ฐฑ์ด ์ธ๋ผ์ธ ํ•จ์ˆ˜๋กœ ์„ ์–ธ๋˜์žˆ๋‹ค๋ฉด ref ์ฝœ๋ฐฑ์€ ์—…๋ฐ์ดํŠธ ๊ณผ์ • ์ค‘์— ์ฒ˜์Œ์—๋Š” null๋กœ, ๊ทธ ๋‹ค์Œ์—๋Š” DOM ์—˜๋ฆฌ๋จผํŠธ๋กœ, ์ด ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ˜„์ƒ์€ ๋งค ๋ Œ๋”๋ง๋งˆ๋‹ค ref ์ฝœ๋ฐฑ์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋ฏ€๋กœ React๊ฐ€ ์ด์ „์— ์‚ฌ์šฉ๋œ ref๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์ƒˆ ref๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ˜„์ƒ์€ ref ์ฝœ๋ฐฑ์„ ํด๋ž˜์Šค์— ๋ฐ”์ธ๋”ฉ๋œ ๋ฉ”์„œ๋“œ๋กœ ์„ ์–ธํ•จ์œผ๋กœ์จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋งŽ์€ ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ํ˜„์ƒ์€ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.

Is this page useful?Edit this page