렌더링 : 코드로 정의된 내용이 실제 브라우저 화면에 그려지는 과정
-> 대표적으로 아래 5가지 정도의 렌더링 상황이 있다.
1. state의 교체 ( useState , disaptch)
2. 부모 컴포넌트의 재렌더링
3. Root.render(…) 함수 호출 (react 18) / react18 이전은 ReactDOM.render(…)
4. props의 교체
5. 중앙 상태값 ( Redux,Mobx,Recoil, ConText Api 등)의 변화
UseRef vs UseState
UseRef → 값이 변화할 때마다 리렌더링이 이루어지지 않는다.
UseState → 상태가 변화할 때마다 리렌더링이 이루어진다.
const [value,setValue]=useState(초기값)
문제점 : 백엔드로 보낼 input의 value값을 onChange를 이용해 useState에 저장하였다.
이렇게 되면, 텍스가 입력될 때마다 리렌더링이 발생해 불필요한 리렌더링이 지속적으로 발생하여 성능에 좋지 못했다.
그래서 아래와 같이 useState를 useRef를 이용하여 개선시켜보았다.
개선 전 코드
(1) 댓글 input 박스에 텍스트를 입력한다.
(2) 입력시마다 useState에 텍스트가 저장된다.
(3) 버튼 클릭 시,useState에 저장되있는 텍스트를 api실행으로 백엔드에 보내준다.
(3) 텍스트값이 MYSQL에 INSERT된다
(4) MYSQL에 저장된 댓글을 불러와 클라이언트에 보여준다.
개선 후 코드
(1) 댓글 input 박스에 텍스트를 입력한다.
(2) 댓글 입력 완료 버튼 클릭 시 , useRef를 이용해 텍스트값을 추출한다.
(3) 추출 된 값을 백엔드로 보낸다.
(4) 텍스트 값이 MYSQL에 INSERT되고 , 댓글을 불러와 클라이언트에 보여준다.
// TS 코드
// (insertContext = api통신에 쓰여질 데이터)
const [insertContext, setInsertContext] = useState<string>("");
const handleContext = (e: React.ChangeEvent<HTMLInputElement>) => {
setInsertContext(e.target.value);
};
//text의 값을 백엔드로 보낸다.
const handleSubmit = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
const axiosData = {
CO_CONTEXT: insertContext,
S_IDX,
};
const result = axiosInstance.post("/clubDetail/insertContext", axiosData);
setInsertContext("");
};
//JSX 코드
<input type="text" placeholder="댓글을 입력해주세요"
className="w-4/5 ml-1 border-y-neutral-800"
onChange={handleContext}
value={insertContext}/>
현재 필요한 데이터는 버튼을 클릭했을 때, input value값이다.
하지만 위 코드에서는 텍스트가 변화할때마다 useState의 값이 변화하여,계속되어 불필요한 리렌더링이 발생하여 성능 저하의 요인이 된다.
// TS
const insertText = useRef<HTMLInputElement>(null);
const handleSubmit = (event: React.MouseEvent<HTMLButtonElement>) => {
const data = insertText.current?.value;
event.preventDefault();
const axiosData = {
CO_CONTEXT: data,
S_IDX,
};
const result = axiosInstance.post("/clubDetail/insertContext", axiosData);
if(insertText.current){
insertText.current.value='';
}
};
// JSX
<input type="text" placeholder=" 댓글을 입력해주세요"
className="w-4/5 ml-1 border-y-neutral-800" ref={insertText}/>
useRef를 이용하여 input value 값을 참조할 수 있게 변경하였다.
이렇게 하여 , 값의 변화에 따른 불필요한 리렌더링이 일어나지 않게 되어 성능 측면에서 더 좋아졌다.
구글이나 네이버에서의 검색 기능을 사용할 때는,텍스트창의 value에 따라 지속적으로 결과를 보여줘야하기에, 리렌더링이 필요하기에 useState를 이용한 방법이 더 옳을 수 있다.
그러나 위와 같은 경우에는, 지속적인 변화에 따라 변화되는 것이 아닌 버튼을 눌렀을 때의 값만을 백엔드로 보낼 데이터만 필요하기에 useRef를 이용한 방법이 좀 더 효율이 좋다.