[React Study]비제어 컴포넌트

Mayton·2022년 6월 18일
0

React

목록 보기
4/10
post-thumbnail
post-custom-banner

비제어 컴포넌트란?

공식문서

우선 제어컴포넌트는 input, textarea, select와 같은 폼 엘리먼트를 사용하여 자신의 state를 관리하고 업데이트 하는 방식을 말한다.

비제어 컴포넌트는 폼엘리먼트를 이용하지 않고, 직접 DOM에서 폼을 가져와서 state를 업데이트 하는 것을 말한다.

ref 사용법

//class component 에서의 ref
class FileInput extends React.Component{
  constructor(props){
    this.fileInput= React.createRef();
  }

  render(){
    return (
      <input type="file" ref={this.fileInput}/>
  }
  
 //function component에서의 ref
 function FileInput(){
   const fileInput=useRef();
   
   return(
     <input type="file" ref={fileInput}/>
   )
 }
  • 포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할때,
    - 폼 안의 개별 영역을 선택하고, 폼의 본래 목적이 아닌 다른 기능을 실행하려고 할때
  • 애니메이션을 직접적으로 실행시킬 때,
  • 서드파티 DOM 라이브러리를 React와 같이 사용할 때

forwardRef

커스텀 클래스 컴포넌트에서는 ref객체는 마운트된 컴포넌트의 인스턴스들을 current 프로퍼티의 값으로 받는다. 그래서 자식 컴포넌트의 메서드를 부모 컴포넌트에서 실행할 수 있다. 하지만, 자식컴포넌트가 함수형으로 작성되었다면 함수 컴포넌트는 인스턴스가 없기 때문에 사용할 수 없다.

공식문서

자식 컴포넌트 안의 엘리먼트 등을 확인하기 위해 forwardRef(높은 확률로 useImperativeHandle을 사용)를 사용할 수 있다.

  • 사용예시
function CatParent(){
  const catRef= useRef();
  
  return(
    <Cat ref={catRef}/>
  )
}


const Cat = forwardRef((props,ref)=>{
  const inputRef=useRef();
  useImperativeHAndle(ref, ()=>({
    focus:()=>{
      inputRef.current.focus();
    }
  }));
  return (
  	<div>
    <input ref={inputRef}/>
    </div>
  )
}

mutable Object

공식문서

useRef는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환한다. 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지될 것 이다. (==useState와 같이 사용할 수 있다.) useRef는 매번 렌더링 할 때 동일한 ref 객체를 제공하며, 내용이 변경될 때 그것을 알려주지 않는다.

function Timer(){
  const intervalRef =useRef();
  
  useEffect(()=>{
    const id = setInterval(()=>{
      //...
    });
    intervalRef.current = id;
    return()=>{
      clearInterval(intervalRef.current);
    };
  });
  //...
}

clearInterval을 해야하고, 변경이 있을 때 리렌더링을 시키지 않고 싶은 위와같은 상황에서 자주 사용된다.

callback ref

함수를 ref에 넘겨 주는것

콜백 ref를 사용하면 자식 컴포넌트가 나중에 측정된 노드를 표시하더라고 여전히 부모 컴포넌트에서 이에 대한 알림을 받고 측정을 업데이트 할 수 있다.

const catCallbackRef=(node)=>{
  if(node!==null){
    alert(node);
    alert(node.getBoundingClientRect().height);
    setHeight(node.getBoundingClientRect().height);
  }
};


return (
  <Cat ref={catCallbackRef}/>
)

//cat

const Cat = forwardRef((props,ref)=>{
  
  return (
    <h1 ref={ref}>text text</h1>
)
profile
개발 취준생
post-custom-banner

0개의 댓글