[React] 비제어 컴포넌트

bbung95·2023년 1월 17일
0

React

목록 보기
5/8
post-thumbnail

비제어 컴포넌트

제어컴포넌트의 대안 방법으로 비제어 컴포넌트를 사용할 수 있습니다.

js에서 Input에 에 값을 변경하고 제어하는 방법으로 2가지가 있다고 했습니다.

  • 이벤트를 통한 input 값 관리
  • DOM을 통한 input 관리

비제어 컴포넌트는 DOM 자체에서 데이터를 다루게 됩니다.
하지만 form에 대한 구현은 제어 컴포넌트를 사용하는것이 좋습니다.

Ref

ref는 render 메서드에서 생성된 DOM 노드나 React 엘리먼트에 접근하는 방법을 제공합니다.

1. Focus, 텍스트 선택 영역을 관리할 때
2. 애니메이션을 직접적으로 실행시킬 때
3. 서드 파티 DOM 라이브러리를 사용할 때

useRef

리엑트에서는 가상돔을 사용하기에 js와 같이 selector를 사용하여 DOM에 접근할 수 없습니다.

함수형 컴포넌트에서 Ref를 사용하려면 훅 함수인 useRef를 사용해야합니다.

useRef로 선언한 변수를 제어하고자 하는 요소에 넣어 제어할 수 있습니다.

React

import React, { useRef } from "react";

const ref = useRef();

useEffect(() => {
	// img DOM
	console.log(ref.current)
},[])

// ...
<Img ref={ref} />
  • 생성된 ref를 제어하고자 하는 요소에 ref속성 값으로 적어줍니다.
  • current로 요소를 가져올 수 있습니다.

forwardRef

부모컴포넌트에서 자식 요소를 제어하려면 ref를 넘겨주어야합니다.

자기 자신의 컴포넌트는 ref를 통해 쉽게 제어가 가능합니다.
하지만 자식 컴포넌트의 제어는 ref를 넘겨준다고 동작하지 않습니다.

함수형에서는 forwordRef를 사용하라고 정의되어 있습니다.

React

import React from "react";

const Img = forwordRef((props, ref) => {

	useEffect(() => {
		// img DOM
		console.log(ref.current)
	},[])

	// ...
	<img ref={ref} />
});
💡 useImperativeHandle

  - ref를 사용할 때 부모 컴포넌트에 노출되는 인스턴스 값을 사용자화합니다.
  - forwordRef와 같이 많이 사용됩니다.

상태값 저장

ref는 요소를 제어하는것 뿐만 아니라 state와 같이 상태를 저장할수 있습니다.

import React, { useRef } from "react";

const valueRef = useRef(1);

<button onClick={() => valueRef.current = valueRef.current + 1}>증가</button>
  • 코드와 같이 useState처럼 초기값을 설정하고 current를 통해 값을 변경 할 수 있습니다.
  • useState와 다른 점으로는 값이 변경되더라도 리랜더링이 발생하지 않는다는 점이 있습니다.

callback Ref

ref는 랜더링을 시키지 않는다고 했습니다. 하지만 useRef 대신 callback 함수를 넣어 변경할 수 있습니다.

// parent component
const [state, setState] = useState(0);

const callbackRef = (node) => {
	if(node !== null){
		setState(node.getBoundingCLientRect().height);
	}
}
// ...
<div>상태값 : {state}</div>
<Img ref={callbackRef}/>

// children compoent
const Img = forwordRef((props, ref) => {

	// ...
	<img ref={ref} src=""/>
});
  • 만약 위와 같이 코드를 작성했을경우 상태값이 변하지 않은것을 확인 할 수 있습니다.
  • 렌더링이 되었을 경우에 img가 로딩중일때 dom이 정상적으로 생성되지 않아 이미지의 높이를 가져올 수 없습니다.
// children compoent
const [loading, setLoading] = useState(false);

const Img = forwordRef((props, ref) => {

	// ...
	<img
		ref={loading ? ref : () => undefined}
		onLoad={() => setLoading(true)}
		src=""
	/>
});
  • onLoad 이벤트를 통해 DOM이 로딩이 된후 ref함수가 동작하도록 설정하여 state의 값을 정상적으로 가져올 수 있습니다.

0개의 댓글