본문 바로가기

React

[React] - ref 알아보기

 

리액트로 개발을 하다보면 돔 요소에 직접 접근해야 할 때가 있다  예를 들어 돔 요소에 포커스를 주거나 돔 요소의 크기나 스크롤 위치를 알고 싶은 경우이다 이때 ref속성값을 이용하면 자식 요소에 직접 접근할 수 있다 자식요소는 컴포넌트 일수도 있고 돔 요소일 수도 있다.

 

 

useRef 훅이 반환하는  ref 객체를 이용해서 자식 요소에 접근할 수 있다.접근하고자 하는 자식 요소의 ref 속성값에 ref 객체를 입력한다 해당 돔 요소 혹은 컴포넌트가 생성되면  ref 객체로 접근할 수 있다.

 

ref 객체의 current 속성을 이용하면 자식 요소에 접근할 수 있다.

위 코드에서는 useEffect 훅 내 부에서 자식 요소에 접근하고 있다 그 이유는 부수 효과 함수는 컴포넌트 렌더링 결과가 돔에 반영된 후에 호출되므로 해당 돔 요소는 이미 생성된 상태이다 

 

* ref 속성값 활용하기

 

클래스형 컴포넌트에 ref 속성값을 입력하면 ref.current는 해당 컴포넌트의 인스턴스를 가리킨다 따라서 ref.current로 해당 클래스의 메서드를 호출할 수 있다.

 

함수형 컴포넌트는 인스턴스로 만들어지지 않지만 useImperativeHandle 훅을 사용하면 함수형 컴포넌트에서도 변수와 함수를 외부토 노출시킬 수 있다 .

 

함수형 컴포넌트에서는 ref 속성값을 입력할 수는 없지만 다른 이름으로  ref 객체를 입력받아서 내부의 리액트 요소에 연결할 수는 있다.

 

 

위 코드를 보면 TextInput 컴포넌트는 inputRef 속성을 input 요소의 ref 속성값으로 넣고 있다 

위 방법은 TextInput 컴포넌트의 내부구조를 외부에서 알아야 하므로 좋지는 않은 방법이다

또한 추가적으로 위 코드에서 InputRef라는 독자적인 이름의 속성 값을 사용했지만 일관성을 위해 ref라는 이름을 사용하는게 좋다 하지만 컴포넌트에 ref속성값을 사용하면 리액트가 내부적으로 처리하기 때문에 순차요소에 연결할 수 없다 이런경우 forwardRef 함수를 사용한다.

 

 

forwardRef 함수를 이용하면 부모컴포넌트에서 넘어온 ref 속성값을 직접 처리할 수 있다 그리고 이전 코드에서 inputRef로 사용했던 이름을 리액트의 예약어인 ref로 사용할 수 있게 됐다

 

* ref 속성값으로 함수 사용하기 

 

ref 속성값에 함수를 입력하면 자식요소가 생성되거나 제거되는 시점에 호출된다.

 

 

 

위 코드를 보면  ref 값으로 함수가 입력되어 있다 ref 속성값으로 입력된 함수는 해당 요소가 제거되거나 생성될 때마다 호출된다 요소가 생성될 때는 해당 요소를 참조하는 변수가 넘어오고 삭제될때는 null 값으로 넘어온다 따라서 해당 요ㅛ소가 생성될 때만 INITIAL_TEXT가 입력되도록 했다

 

하지만 위 코드는 의도한 대로 동작하지 않는다 컴포넌트가 렌더링될때마다 새로운 함수를 ref 속성값으로 넣기 때문이다 리액트는 ref속성값으로 새로운 함수가 들어오면 이전 함수에 null인수를 넣어서 호출하고 새로운 함수에는 요소의 참조값을 넣어서 호출한다 따라서 텍스트를 입력하면 컴포넌트가 렌더링되고 ref 속성값에 입력된 새로운 함수가 호출되면서 INITIAL_TEXT로 덮어 쓰는 것이다 이러한 문제는 다음과 같이 해결 할 수 있다.

 

useCallback 훅을 이용해서 setInitialText 함수를 변하지 않게 만들었다 useCallback 훅의 메모이제이션 기능 덕분에 한번 생성된 함수를 계속 재사용 할 수 있다.

 

* ref 사용할때 주의할 점 

 

 

컴포넌트가 생성된 이후라고 ref 객체의 current 속성이 없을 수 있기 때문에 주의해야 한다.

위 코드는 ref 속성값을 입력한 input 요소는 showText 상탯값에 따라 존재하지 않을수도 있다 이렇게 조건부 렌더링을 하는 경우에는 컴포넌트가 생성된 이후라 하더라도 ref객체를 사용할 때 주의해야 한다 

결과적으로 조건부 렌더링이 사용된 요소의 ref객체는 current 속성을 검사하는 코드가 필요하다 .

 

'React' 카테고리의 다른 글

[React] - useReducer  (0) 2022.09.05
[React] - useMemo, useCallback  (0) 2022.08.06
[React] - Context API  (0) 2022.07.12
[React] - Custom Hook  (0) 2022.04.16
[React] - useState 파헤치기  (0) 2022.04.15