我只是在深入研究React。但是 useEffect React钩子仍然让我感到困惑。我知道我可以将依赖项作为数组传递给它来控制组件的呈现。我已经使用了props和local state来做这件事,它工作正常。
让我仍然困惑的是当我把redux reducer作为一个依赖项传递时,它会导致渲染组件的无限循环。
* 用户 * 组件
const usersComp = () => {
const users = useSelector(state => state.users);
useEffect(
// Fetch users and update users state
useDispatch().dispatch(getUsers)
,[users]) // <-- Causes an infinite loop!!
if(users.length){
return( users.map(user => <p>{user}</p>))
}
}
getUsers还原形式转换函数
export async function getUsers(dispatch, getState) {
fetch(endpoint)
.then(response => response.json())
.then(users => {
dispatch({type: GET_USERS, payload: users})
}).catch(err => console.error("Error: ", err));
}
* 用户 * 减速器
export default function usersReducer(state = [], action) {
switch (action.type) {
case GET_USERS : {
return [...state, action.payload]
}
}
}
据我所知,users 一开始是一个空数组,然后被API调用的数据填充,所以 useEffect 应该触发两次;当组件刚被挂载时,以及当用户状态从API调用中改变时。那么,是什么导致了无限循环呢?
1条答案
按热度按时间qv7cva1a1#
从
useEffect
依赖项中删除users
,因为您希望在组件挂载时获取用户,而不是每次users
更改时获取用户。说明:
所以,如果你在 * 案例2 * 中执行
fetch
,它将 * 改变 *users
,这将重新触发钩子,这将再次fetch
用户,这将改变users
,并导致钩子重新触发→这是一个无限循环。更新:
为什么
useEffect
检测到state.users
发生变化(在此代码中),即使state.users
的值为"SAME"(相同值)?每当调度
GET_USERS
操作时,reducer返回newstate({ ...state, users: action.payload })
。即使action.payload
的值包含相同的用户值,它也会这样做。这就是useEffect
接收newusers数组的原因。(它们进行浅层比较。)注意,
[1, 2,3] is not equal to [1, 2,3]
即[1, 2,3] === [1, 2,3]
返回假。如果出于某种原因,你想返回相同的redux状态,在reducer中执行
return state
,这通常是我们在reducer的switch
的default
情况下所做的。