인프런 커뮤니티 질문&답변

skj3232님의 프로필 이미지
skj3232

작성한 질문수

실전 리액트 프로그래밍

ref 속성값으로 자식 요소에 접근하기

ref에 함수를 입력하는 부분에서 질문이 있습니다.

해결된 질문

작성

·

350

0

<input ref={ref => ref && setText(INITIAL_TEXT)}> 여기에서 화살표 함수를 사용해서 input이 생성될 때는 input이 함수의 매개변수에 담기게 되고 사라질 때는 null값이 넘어와서 null 값일때는 setText가 실행되지 않는다는 것은 이해했습니다. 그런데 그러면 저 함수에서 리턴값은 어떻게 되는건가요? ref = {}에서 ref에는 실질적으로 값이 담기는 것은 아닌가요?
 
import React, { useState } from 'react';

export default function App() {
  const [text, setText] = useState(INITIAL_TEXT);
  const [showText, setShowText] = useState(true);
  return (
    <div>
      {showText && (
        <input
          type="text"
          ref={(ref) => {
            ref && setText(INITIAL_TEXT);
            console.log(ref);
          }}
          value={text}
          onChange={(e) => setText(e.target.value)}
        />
      )}
      <button onClick={() => setShowText(!showText)}>보이기/가리기</button>
    </div>
  );
}

const INITIAL_TEXT = '안녕하세요';
 
또한 위의 코드에서 console을 찍어봤을 때 input 입력창에 키보드 입력을 하게 되면 콘솔이 두번 찍히게 되는데 이것은 어떤 이유에서 그런걸까요?

답변 1

1

이재승님의 프로필 이미지
이재승
지식공유자

안녕하세요

저 함수에서 리턴값은 어떻게 되는건가요?
ref 함수의 반환값은 사용되지 않습니다 (의미 없음)

ref = {}에서 ref에는 실질적으로 값이 담기는 것은 아닌가요?
우리가 전달한 ref 함수가 레퍼런스(돔 참조) 값이 되는 것은 아닙니다.
단지 레퍼런스가 변경될 때 실행되는 콜백 함수일 뿐입니다.

skj3232님의 프로필 이미지
skj3232
질문자

아..그렇군요!! 답변 감사드립니다. 혹시 두번째 질문에 입력창에 키보드 입력을 하였을 때 콘솔창에 4개찍히는 원리가 무엇인지도 설명해주실 수 있을까요..?

이재승님의 프로필 이미지
이재승
지식공유자

렌더링 할 때마다 새로운 ref 함수가 입력되서 그렇습니다
리액트는 ref 속성으로 새로운 함수가 입력되면 이전 함수를 null 매개변수와 함께 호출하고, 새로 입력된 함수는 돔 요소의 레퍼런스와 함께 호출합니다
성능 최적화를 원한다면 아래처럼 작성할 수 있습니다

  const onRef = useCallback(ref => {
    ref && setText(INITIAL_TEXT);
    console.log(ref);
  }, []);
  // ...
  <input ref={onRef} ...

 

로그가 2개가 아니라 4개가 찍히는 이유는 strict mode 때문일 수 있는데요
React.StrictMode 가 사용됐는지 봐주시면 될 것 같아요

https://reactjs.org/docs/strict-mode.html

skj3232님의 프로필 이미지
skj3232
질문자

답변 감사합니다!! React.StrictMode가 index.js 파일에 있었는데 이를 삭제하고도 로그가 4개 찍힙니다..ㅠㅠ App.js는 같고 다음은 index.js 파일입니다.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <>
    <App />
  </>,
  document.getElementById('root'),
);

 

 

 

이재승님의 프로필 이미지
이재승
지식공유자

그렇다면 아마도 setText 호출로 다시 렌더링 되면서 찍히는 것 같네요
위의 예처럼 useCallback 을 사용한다면 입력할 때 로그가 출력되지 않을 것 같습니다

skj3232님의 프로필 이미지
skj3232
질문자

앗 맞습니다 위의 예처럼 useCallback을 사용하면 로그가 출력되지 않습니다! 끝까지 답변해주셔서 감사드립니다!!

skj3232님의 프로필 이미지
skj3232

작성한 질문수

질문하기