- state 초기값을 전달할 때 함수형과 기본값 차이는 무엇일까요?
state에 대해서 깊에 공부하다가 동료분이 남겨준 질문을 깊게 고민해 봤다.
useState를 사용할 때는 컴포넌트에서 변할 수 있는 값, 즉 상태를 변경하기 위해 React state를 사용했다.
const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값);
차이는 초기 컴포넌트 마운트
랑 관계가 있다.
// 함수형
import { useState } from 'react';
function createInitialTodos() {
const initialTodos = [];
for (let i = 0; i < 50; i++) {
initialTodos.push({
id: i,
text: 'Item ' + (i + 1)
});
}
return initialTodos;
}
export default function TodoList() {
const [todos, setTodos] = useState(createInitialTodos);
const [text, setText] = useState('');
return (
<>
<input
value={text}
onChange={e => setText(e.target.value)}
/>
<button onClick={() => {
setText('');
setTodos([{
id: todos.length,
text: text
}, ...todos]);
}}>Add</button>
<ul>
{todos.map(item => (
<li key={item.id}>
{item.text}
</li>
))}
</ul>
</>
);
}
함수형 컴포넌트는 컴포넌트가 처음 마운트될 때만 호출되며, 그 이후의 렌더링에서는 호출되지 않는다.
// 기본형
import { useState } from 'react';
function createInitialTodos() {
const initialTodos = [];
for (let i = 0; i < 50; i++) {
initialTodos.push({
id: i,
text: 'Item ' + (i + 1)
});
}
return initialTodos;
}
export default function TodoList() {
const [todos, setTodos] = useState(createInitialTodos());
const [text, setText] = useState('');
return (
<>
<input
value={text}
onChange={e => setText(e.target.value)}
/>
<button onClick={() => {
setText('');
setTodos([{
id: todos.length,
text: text
}, ...todos]);
}}>Add</button>
<ul>
{todos.map(item => (
<li key={item.id}>
{item.text}
</li>
))}
</ul>
</>
);
}
초기 상태를 직접 전달하며 직관적이다. 컴포넌트가 렌더링될 때마다 동일한 초기값이 사용된다.
useState의 첫번째 매개변수로 함수를 넘겨주면 JavaScript 문법상 매 렌더링 시 그 함수가 실행되어 렌더링 성능이 낮아질 수 있다. 그래서 이 경우에 고차 함수 형태로 초기값을 계산하면 불필요한 연산을 방지할 수 있다.
[참고]
Parameters
initialState: The value you want the state to be initially. It can be a value of any type, but there is a special behavior for functions. This argument is ignored after the initial render.
If you pass a function as initialState, it will be treated as an initializer function. It should be pure, should take no arguments, and should return a value of any type. React will call your initializer function when initializing the component, and store its return value as the initial state. See an example below.
규모가 큰 프로젝트가 아닌 이상, 초기값이 함수형과 기본형으로 렌더링 성능의 차이를 크게 못 느낀다.