React useState 호출 시 무조거 렌더링이 된다?
정답은...! 아니다 입니다.
1. state가 원시타입일 경우 (Number, String, boolean, null, undefined )
-> setState 호출 이전의 state값과 새롭게 갱신된 state 값을 비교( 이전값 === 새로운값) 한 뒤 같지 않으면 렌더링이 이뤄지고 아니면 렌더링이 발생하지 않습니다.
2. state가 원시타입이 아니고 참조 타입(object, Symbol) 일 경우
->위와 같은 방식으로 값 자체를 비교하지 않고 메모리 주소를 비교하여 렌더링이 발생할지 말지를 결정합니다. 실제론 동일한 형태의 객체여도 렌더링이 발생할 수 있다는 말이죠
export const Component =() =>{
const [state,setState] =useState(0) // state가 원시 타입일 경우
useEffect(()=>{
console.log("컴포넌트 렌더링 됨");
})
return (
<>
// 버튼 클릭 시 렌더링 일어나지 않음
<button onClick={()=>{
console.log("클릭됨");
setState(0)
}}>버튼</button>
</>
)
}
위 코드를 보면 버튼을 클릭 해도 기존 state값과 바뀔 state의 값이 둘다 0 이기 때문에 컴포넌트는 setState가 호출 되어도 렌더링이 일어나지 않습니다. 하지만 만약 갱신될 값이 달랐다면 분명히 렌더링이 일어날 것 입니다.
export const Component =() =>{
const [state,setState] =useState({key:value}) // state가 참조 타입 일 경우
useEffect(()=>{
console.log("컴포넌트 렌더링 됨");
})
return (
<>
// 버튼 클릭 시 렌더링 일어나지 않음
<button onClick={()=>{
console.log("버튼 클릳 됨")
setState((prev)=> prev) // 재 렌더링 일어나지 않음
setState({key:value}) // 재 렌더링 일어남
}}>버튼</button>
</>
)
}
위 코드의 12번째, 13번째 줄의 코드는 결과적으로 동일한 state를 갖도록 하는 setState이지만 하나는 렌더링을 발생시키고 하나는 렌더링이 일어나지 않습니다. 이는 state가 참조 타입일 경우 setState 호출 시 state를 가리키는 메모리 주소를 비교하여 메모리 주소가 동일한 경우 재 렌더링을 발생시키지 않는 것임을 알 수 있습니다.
'React' 카테고리의 다른 글
react lazy loading 처리 방법 ( suspense와 lazy 이용 ) (0) | 2024.01.24 |
---|---|
비즈니스 로직 어떻게 분리할까? (1) | 2023.11.23 |
zustand useshallow는 언제쓸까? (2) | 2023.11.19 |
useCallback를 사용하는 이유 (0) | 2023.11.19 |
useMemo를 사용하는 이유 (0) | 2023.11.19 |