我试图了解useEffect如何处理对象。
这是一个示例,将帮助演示我的问题:
export function UseEffectHook() {
const initialState = {
firstName: "Joe",
lastName: "Smith",
address: {
home: "123 street"
}
};
const [user, setUser] = useState(initialState);
const [count, setCount] = useState(0);
useEffect(() => {
console.log("triggered");
}, [user]);
return (
<div>
<p>useEffect - Practice with different deps</p>
{JSON.stringify(user)}
<label>Firstname:</label>
<input
type="text"
onChange={e => setUser({ ...user, firstName: e.target.value })}
/>
<br />
<label>Lastname:</label>
<input
type="text"
onChange={e => setUser({ ...user, lastName: e.target.value })}
/>
<button onClick={() => setCount(count + 1)}>Button</button>
</div>
);
}
我已经读过,由于在重渲染之间比较对象的方式,将对象作为依赖项放置在useEffect挂钩中不起作用。
我最初的想法是在此示例中单击按钮,并且更新计数还应导致useEffect挂钩被更新。情况并非如此,useEffect不会重新运行。
我无法找到足够人为的示例来帮助演示何时以及为何使用对象重新运行useEffect。任何帮助将不胜感激。
使用您的组件。
更改:
initialState
移动到UseEffectHook之外。您不需要创建initialState
每次重新渲染;setUser
和setCount
和updater function;handleOnChangeUser
能够用于用户对象的所有字段。每次handleOnChangeUser-创建对用户对象的新引用。在这种情况下,useEffect能够检测到更改;import React, { useCallback, useEffect, useState } from 'react';
const initialState = {
firstName: "Joe",
lastName: "Smith",
address: {
home: "123 street",
}
};
export function UseEffectHook() {
const [user, setUser] = useState(initialState);
const [count, setCount] = useState(0);
const handleOnChangeUser = useCallback((event) => {
const { name, value } = event;
setUser(prevState => ({ ...prevState, [name]: value }));
}, []);
const increaseCount = useCallback(() => {
setCount(prevState => prevState + 1);
}, []);
useEffect(() => {
console.log("triggered");
}, [user]);
return (
<div>
<p>useEffect - Practice with different deps</p>
{JSON.stringify(user)}
<label>
<span>Firstname:</span>
<input
type="text"
name="firstName"
onChange={handleOnChangeUser}
/>
</label>
<br />
<label>
<span>Lastname:</span>
<input
type="text"
name="lastName"
onChange={handleOnChangeUser}
/>
</label>
<button onClick={increaseCount}>Increase</button>
</div>
);
}
useEffect将在其依赖项数组中的任何对象更改引用时重新运行。
例如,在您的代码中,在调用setUser之前,用户始终是稳定的,在这种情况下,它将更改为新引用并在该位置运行。
如果改为在每个渲染中将用户定义为一个新对象,则useEffect将在每次重新渲染组件时运行。
const user = {
firstName: 'Joe',
lastName: 'Smith',
address: {
home: '123 street',
},
};
全部涉及参照相等性。每个渲染器上是否为previousUser === newUser。对于依赖数组中的每个变量,React本质上都执行与检查(我相信Object.is)非常相似的检查。