[英]React redux reducer as UseEffect dependency causes infinite loop
我只是深入反应。 但是 useEffect 反应钩子仍然让我感到困惑。 我知道我可以将依赖项作为数组传递给它来控制组件的渲染。 我已经使用道具和本地 state 来做并且它有效。
让我仍然感到困惑的是,当我将 redux 减速器作为依赖项传递时,它会导致渲染组件的无限循环。
// 用户组件
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 Redux Thunk function
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]
}
}
}
据我了解,用户从一个空数组开始,然后填充来自 API 调用的数据。 所以 useEffect 应该触发两次; 当组件刚刚安装时,然后当用户 state 从 API 调用更改时。 那么是什么导致了无限循环呢?
从useEffect
依赖项中删除users
,因为您希望在组件安装时获取用户,而不是每次更改users
时。
useEffect(
useDispatch().dispatch(getUsers)
,[]) // Now, it will fetch users ONLY ONCE when component is mounted
解释:
// Case 1
useEffect(() => {
console.log("Mounted") // printed only once when component is mounted
}, [])
// Case 2
useEffect(() => {
console.log("users changed") // printed each time when users is changed
}, [users])
因此,如果您在案例 2中进行fetch
,它将更改users
,这将重新触发钩子,该钩子将再次fetch
用户,从而更改users
并导致钩子重新触发 ---> 这是一个无限循环。
state.users
正在发生变化(在此代码中),正如useEffect
检测到的那样,即使state.users
的值是“相同的”(相同的值)? 每当GET_USERS
操作时,reducer 都会返回新的state ( {...state, users: action.payload })
,即使action.payload
的值与用户的值相同,它也会这样做。 这就是useEffect
接收新用户数组的原因。 (他们做了浅显的比较)。
请注意, [1, 2,3] is not equal to [1, 2,3]
即[1, 2,3] === [1, 2,3]
返回 false。
如果由于某种原因,您想返回相同的 redux state,请在减速器中return state
。 这通常是我们在 reducer switch
的default
情况下所做的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.