제어컴포넌트(controlled component)
아래는 공식문서에 나오는 설명입니다.
제어 컴포넌트는 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트합니다. React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState()에 의해 업데이트됩니다.
(중략)
이러한 방식으로 React에 의해 값이 제어되는 입력 폼 엘리먼트를 “제어 컴포넌트 (controlled component)“라고 합니다.
export default function App() {
const [input, setInput] = useState("");
const onChange = (e) => {
setInput(e.target.value);
};
return (
<div className="App">
<input onChange={onChange} />
</div>
);
}
인풋창에 입력을 할때마다 랜더링이 일어난다. 즉, 제어 컴포넌트는 사용자가 입력한 값과 저장되는 값이 실시간으로 동기화된다. (항상 최신값을 유지)
이러한 경우 불필요한 리렌더링과 api 요청이 일어날 수 있으므로, 쓰로틀링이나 디바운싱을 통하여 막을 수 있습니다.
쓰로틀링: 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것
디바운싱: 연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것
비제어 컴포넌트 (uncontrolled component)
비제어 컴포넌트는 기존의 바닐라 자바스크립트와 크게 다르지 않은 방식으로 실시간으로 동기화되지 않는다.
제어 컴포넌트가 사용자가 입력을 하는 액션이 발생될 때마다 리렌더링을 발생시키는 반면, 비제어 컴포넌트는 사용자가 직접 트리거하기 전까지는 리렌더링을 발생시키지도 않고 값을 동기화도 시키지 않습니다.
export default function App() {
const inputRef = useRef(); // ref 사용
const onClick = () => {
console.log(inputRef.current.value);
};
return (
<div className="App">
<input ref={inputRef} />
<button type="submit" onClick={onClick}>
전송
</button>
</div>
);
}
인풋창에 useRef()를 사용하여, 직접 Dom을 핸들링할 수 있다. (입력할 때마다 랜더링이 일어나지 않음)
근데 개인적으로 validation 유효성검사를 진행하는 회원가입폼같은 곳에서는 실시간으로 입력값을 받아오는 것이 적절하다고 생각한다.
그럼 왜 비제어 컴포넌트를 사용할 땐 useRef를 사용하고,
이러한 useRef는 왜 리렌더링을 발생시키지 않는 걸까요?
useRef()는 heap영역에 저장되는 일반적인 자바스크립트 객체이다. 매번 렌더링 할 때 동일한 객체를 제공한다. heap에 저장되어 있기 때문에 애플리케이션이 종료되거나 가비지 컬렉팅 될 때까지, 참조할 때마다 같은 메모리 값을 가진다고 할 수 있다. 값이 변경되어도 리렌더링이 되지 않는다.
결론: 같은 메모리 주소를 갖고 있기 때문에 자바스크립트의 === 동치 연산이 항상 true를 반환한다. 즉 변경사항을 감지할 수 없어서 리렌더링을 하지 않는다는 뜻이다.
'React' 카테고리의 다른 글
CSS 모달창을 만들어보자구나! (0) | 2022.11.18 |
---|---|
react-hook-form 사용기 (0) | 2022.11.15 |
리액트 geolocation으로 내 위치 좌표값 가져오기 (0) | 2022.11.09 |
useEffect() 가 뭐꼬? (0) | 2022.10.08 |
리액트를 시작하는 첫 걸음 (0) | 2022.09.29 |