React로 프로그램을 작성하다보면 굳이 상태로 만들지 않아도 되는 값들을 useState
를 이용하여 만드는 경우가 있다.
상태가 많아질수록 결국 리액트가 관리하는 포인트가 많아지게 되고, 불필요한 리렌더링을 초래할 가능성이 많아진다.
이러한 실수를 자주 사용하게 되는 경우를 알아보았다.
값을 읽기만 하고, 업데이트는 되지 않는 경우가 있다. (상수 등)
const INFO = {
name: 'component',
value: 'clean code',
};
// 별로 좋지 않은 방법이다.
// const [info, setInfo] = useState(INFO)
이런 경우는 state로 선언하지도 말고, 컴포넌트안에 배치 하는 것이 아닌 바깥에 배치하는 것이 좋다.
컴포넌트 안에 있다면 리렌더링시 매번 재생성하게 되고, 이는 메모리면에서 악영향을 줄 수도 있다.
const INFO = {
name: 'component',
value: 'clean code',
};
const NotUpdateValue = () => {
// ...
return <div>{INFO.name}</div>
}
컴포넌트를 작성하다보면 isLoading
, isMounted
와 같은 상태를 사용할 때가 있다.
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
setIsLoading(false);
}, [])
이러한 상태는 컴포넌트와 생명주기를 같이한다. 값이 변하고 나면 다시는 변하지 않는다.
즉, 컴포넌트가 사라질 때까지 일관적인 정보를 제공한다.
이런 경우는 useRef
를 이용해서 만들어 주면 상태를 줄여 불필요한 리렌더링을 방지할 수 있다.
const isLoading = useRef(false);
useEffect(() => {
// X
// setIsLoading(true)
isLoading.current = true;
return () => {
isLoading.current = false;
}
}, []);
여러 값들의 조건을 통해 불리언 값을 만들고, 이를 통해 제어하는 경우가 있다.
const [isLogin, setIsLogin] = useState(false);
useEffect(() => {
if (hasToken) setIsLogin(true);
if (hasSession) setIsLogin(true);
// ...
}, [])
return <div>{isLogin && 'Hello'}</div>
이런 경우 그냥 일반 변수로 빼주어도 상관없다. 어차피 매렌더링마다 다시 계산이 되기 때문이다.
const isLogin = (hasToken || hasSession) && isValidUser // ... 여러 조건
return <div>{isLogin && 'Hello'}</div>