⛏ state 선언 위치에 따른 rendering 차이
너무도 당연한 얘기를 실험과 함께 정리해보고자 한다.
솔직히 React를 쓰면서, 'state가 바뀌면, re-rendering이 됩니다!' 정도만 알고 코딩했던 것 같다. 하지만 그런 와중에도
'rendering이 적게 일어나게 하려면 state를 어떤 식으로 나눠야 할까?',
'state를 어떻게 두면 rendering이 많이 일어날까?'
와 같이, state에 따른 rendering에 대한 호기심과 명확히 알아보고자 하는 욕구가 있었다.
여러 경우를 비교하는게 딱히 어려운 일도 아닌데, 자꾸 미뤄온 스스로를 반성하며 당연하지만 눈으로 확인하면 확실하게 기억할 수 있는 시도를 기록해본다.
준비
state는 count라는 숫자와 name이라는 문자열을 준비했다.
실험 case는 다음과 같다.
App.js
에 두 state 모두 선언.- 각 state를 component로 분리하고,
App.js
에 import해서 사용. - state는
App.js
에서 선언하고, stateless component에서 각 state를 받아서 사용. - redux와 같은 전역 상태 관리툴에서 선언.
실험
1️⃣App.js
에 두 state 모두 선언.
코드
// App.js
const App = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState("");
const inputRef = useRef();
return (
<>
{/* Name 부분 코드 */}
<span>{name}</span>
<form
onSubmit={(e) => {
e.preventDefault();
setName(inputRef.current.value);
inputRef.current.value = "";
}}
>
<input ref={inputRef} />
</form>
{/* Count 부분 코드 */}
<span>{count}</span>
<br />
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</>
)
}
결과
=> 전체(App.js
)가 re-rendering 됨.
Name과 Count를 Component로 따로 분류하지 않았기 때문에, App Component 전체가 re-rendering 된다.
2️⃣ 각 state를 component로 분리하고, App.js
에 import해서 사용.
코드
// App.js
const App = () => {
return (
<Name />
<Count />
)
}
// Name.js
const Name = () => {
const [name, setName] = useState("");
return (
<>
{/* Name 부분 코드 */}
</>
)
}
// Count.js
const Count = () => {
const [count, setCount] = useState(0);
return (
<>
{/* Count 부분 코드 */}
</>
)
}
결과
=> 각 component만 re-rendering됨.
3️⃣ state는 App.js
에서 선언하고, stateless component에서 각 state를 받아서 사용.
코드
// App.js
const App = () => {
const [name, setName] = useState("Kim");
const [count, setCount] = useState(0);
return (
<>
<Name name={name} setName={setName} />
<Count count={count} setCount={setCount} />
</>
)
}
// Name.js
const Name = ({ name, setName }) => {
return (
<>
{/* Name 부분 코드 */}
</>
)
}
// Count.js
const Count = ({ count, setCount }) => {
return (
<>
{/* Count 부분 코드 */}
</>
)
}
결과
=> Name이나 Count 둘 중 하나만 바꾸더라도 App, Name, Count 모두 re-rendering 됨.
App이 rendering 되는 건 state 때문이지만, Name과 Count는 state를 props로 전달받았기 때문에, props가 변하면서 rendering 되는 것.
4️⃣ redux와 같은 전역 상태 관리툴 사용
4️⃣-1. redux + 3️⃣번 조건(App.js에 state)
결과
=> 3번 결과와 동일하게 모든 component가 re-rendering됨.
4️⃣-2. redux + 2️⃣번 조건(각 component에 state)
결과
=> 2번 결과와 동일하게 부분적으로 re-rendering됨.
(2번 조건과 결과 동일.)
4️⃣-3. redux + 2️⃣번 조건 + App.js에서 name state 구독 (구독만 하고 사용 X)
구독한 name
을 사용하지는 않고, 구독만 한 상태에서 name state를 변경해봤다.
(return 구문 안에서 name
사용 X)
코드
// App.js
...
const name = useSelector(state => state.name);
...
결과
=> name이 바뀌면 App component도 re-rendering.
4️⃣-4. redux + 2️⃣번 조건 + App.js에서 setName 사용 (name state 구독 X)
App.js
에서 name
을 구독하지 않고, setName
이라는 action만 사용했다.
코드는 Name.js
에 있는 <input>
부분과 동일하다.
코드
// App.js
...
return (
...
<span>input box in App.js</span>
<form
onSubmit={(e) => {
e.preventDefault();
setName(inputRef.current.value);
inputRef.current.value = "";
}}
>
<input ref={inputRef} />
</form>
...
)
결과
=> name
component만 re-rendering됨.
결론
예상한대로 state가 변하면, re-rendering이 발생했다. redux사용 시, 구독한 state가 변하면 역시나 re-rendering되는 것도 확인했다. 조금 신기했던 건, 구독해놓고 render하지 않아도 state의 변화에 반응한다는 점이다. 그리고 state를 구독하지 않고 action만 사용하면 re-rendering 되지 않는 점도 신기했다. 어쩌면 당연한 결과인지도 모르지만, 평소 state와 action을 떼어놓고 사용하지 않다보니 낯선 결과로 느껴졌다.
redux의 경우, reselect를 이용하면 re-rendering을 방지할 수 있다. 자세한 건 다시 공부해고 정리해볼 생각이다.
Author And Source
이 문제에 관하여(⛏ state 선언 위치에 따른 rendering 차이), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@bandor/20211017-TIL저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)