불변인 props, state 및 기타 값을 변이하는 것을 검증합니다.

규칙 세부 사항

컴포넌트의 props와 state는 불변 스냅샷입니다. 절대 직접 변이하지 마세요. 대신 새로운 props를 전달하고, useState의 setter 함수를 사용하세요.

일반적인 위반 사례

잘못된 예시

// ❌ 배열 push 변이
function Component() {
const [items, setItems] = useState([1, 2, 3]);

const addItem = () => {
items.push(4); // 변이!
setItems(items); // 같은 참조, 리렌더링 안 됨
};
}

// ❌ 객체 프로퍼티 할당
function Component() {
const [user, setUser] = useState({name: 'Alice'});

const updateName = () => {
user.name = 'Bob'; // 변이!
setUser(user); // 같은 참조
};
}

// ❌ 스프레드 없이 정렬
function Component() {
const [items, setItems] = useState([3, 1, 2]);

const sortItems = () => {
setItems(items.sort()); // sort는 변이함!
};
}

올바른 예시

// ✅ 새 배열 생성
function Component() {
const [items, setItems] = useState([1, 2, 3]);

const addItem = () => {
setItems([...items, 4]); // 새 배열
};
}

// ✅ 새 객체 생성
function Component() {
const [user, setUser] = useState({name: 'Alice'});

const updateName = () => {
setUser({...user, name: 'Bob'}); // 새 객체
};
}

문제 해결

배열에 항목을 추가해야 하는 경우

push() 같은 메서드로 배열을 변이하면 리렌더링이 트리거되지 않습니다.

// ❌ 잘못된 예: 배열 변이
function TodoList() {
const [todos, setTodos] = useState([]);

const addTodo = (id, text) => {
todos.push({id, text});
setTodos(todos); // 같은 배열 참조!
};

return (
<ul>
{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}

대신 새 배열을 생성하세요.

// ✅ 더 나은 방법: 새 배열 생성
function TodoList() {
const [todos, setTodos] = useState([]);

const addTodo = (id, text) => {
setTodos([...todos, {id, text}]);
// 또는: setTodos(todos => [...todos, {id: Date.now(), text}])
};

return (
<ul>
{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}

중첩된 객체를 업데이트해야 하는 경우

중첩된 프로퍼티를 변이하면 리렌더링이 트리거되지 않습니다.

// ❌ 잘못된 예: 중첩된 객체 변이
function UserProfile() {
const [user, setUser] = useState({
name: 'Alice',
settings: {
theme: 'light',
notifications: true
}
});

const toggleTheme = () => {
user.settings.theme = 'dark'; // 변이!
setUser(user); // 같은 객체 참조
};
}

업데이트가 필요한 각 레벨에서 스프레드하세요.

// ✅ 더 나은 방법: 각 레벨에서 새 객체 생성
function UserProfile() {
const [user, setUser] = useState({
name: 'Alice',
settings: {
theme: 'light',
notifications: true
}
});

const toggleTheme = () => {
setUser({
...user,
settings: {
...user.settings,
theme: 'dark'
}
});
};
}