验证是否修改属性、state 和其他 不可变 值。

¥Validates against mutating props, state, and other values that are immutable.

规则详情

¥Rule Details

组件的属性和状态是不可变的快照。切勿直接突变它们。相反,向下传递新的属性,并使用 useState 中的 setter 函数。

¥A component’s props and state are immutable snapshots. Never mutate them directly. Instead, pass new props down, and use the setter function from useState.

常见违规

¥Common Violations

无效

¥Invalid

// ❌ Array push mutation
function Component() {
const [items, setItems] = useState([1, 2, 3]);

const addItem = () => {
items.push(4); // Mutating!
setItems(items); // Same reference, no re-render
};
}

// ❌ Object property assignment
function Component() {
const [user, setUser] = useState({name: 'Alice'});

const updateName = () => {
user.name = 'Bob'; // Mutating!
setUser(user); // Same reference
};
}

// ❌ Sort without spreading
function Component() {
const [items, setItems] = useState([3, 1, 2]);

const sortItems = () => {
setItems(items.sort()); // sort mutates!
};
}

有效

¥Valid

// ✅ Create new array
function Component() {
const [items, setItems] = useState([1, 2, 3]);

const addItem = () => {
setItems([...items, 4]); // New array
};
}

// ✅ Create new object
function Component() {
const [user, setUser] = useState({name: 'Alice'});

const updateName = () => {
setUser({...user, name: 'Bob'}); // New object
};
}

故障排除

¥Troubleshooting

我需要向数组添加元素

¥I need to add items to an array

使用类似 push() 的方法修改数组不会触发重新渲染:

¥Mutating arrays with methods like push() won’t trigger re-renders:

// ❌ Wrong: Mutating the array
function TodoList() {
const [todos, setTodos] = useState([]);

const addTodo = (id, text) => {
todos.push({id, text});
setTodos(todos); // Same array reference!
};

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

改为创建一个新数组:

¥Create a new array instead:

// ✅ Better: Create a new array
function TodoList() {
const [todos, setTodos] = useState([]);

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

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

我需要更新嵌套对象

¥I need to update nested objects

修改嵌套属性不会触发重新渲染:

¥Mutating nested properties doesn’t trigger re-renders:

// ❌ Wrong: Mutating nested object
function UserProfile() {
const [user, setUser] = useState({
name: 'Alice',
settings: {
theme: 'light',
notifications: true
}
});

const toggleTheme = () => {
user.settings.theme = 'dark'; // Mutation!
setUser(user); // Same object reference
};
}

在需要更新的每个级别上进行扩展:

¥Spread at each level that needs updating:

// ✅ Better: Create new objects at each level
function UserProfile() {
const [user, setUser] = useState({
name: 'Alice',
settings: {
theme: 'light',
notifications: true
}
});

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