Javascript 反应redux reducer,因为UseEffect依赖项导致无限循环

Javascript 反应redux reducer,因为UseEffect依赖项导致无限循环,javascript,reactjs,redux,Javascript,Reactjs,Redux,我正深陷其中。但是这个钩子仍然让我困惑。我知道我可以将依赖项作为数组传递给它,以控制组件的呈现。我用道具和当地政府做的,它的工作 让我仍然困惑的是,当我将redux reducer作为依赖项传递时,它会导致呈现组件的无限循环 //用户组件 const usersComp = () => { const users = useSelector(state => state.users); useEffect( // fetch users and update users

我正深陷其中。但是这个钩子仍然让我困惑。我知道我可以将依赖项作为数组传递给它,以控制组件的呈现。我用道具和当地政府做的,它的工作

让我仍然困惑的是,当我将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>))
}
}

//用户减速器

  export default function usersReducer(state = [], action) {
     switch (action.type) {

        case GET_USERS : {
            return [...state, action.payload]
        }
    }
}
据我所知,用户从一个空数组开始,然后通过API调用填充数据。所以使用效果应该发射两次;当组件刚刚装入,然后当用户状态从API调用更改时。那么是什么导致了无限循环呢?

将用户从useEffect依赖项中删除,因为您希望在组件挂载时获取用户,而不是每次用户更改时

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中进行提取,它将更改用户,从而重新触发钩子,钩子将再次提取用户,从而更改用户并导致钩子重新触发-->这是一个无限循环

更新: 为什么当state.users的值相同时,useffect检测到此代码中的state.users会发生更改? 每当调度GET_USERS操作时,reducer都会返回新状态{…state,USERS:action.payload},即使action.payload的值与USERS的值相同,它也会这样做。 这就是useEffect接收新用户阵列的原因。他们做了肤浅的比较

注意,[1,2,3]不等于[1,2,3],即,[1,2,3]=[1,2,3]返回false

如果出于某种原因,您希望返回相同的redux状态,请在reducer中执行returnstate。这通常是我们在默认情况下切换reducer时所做的操作。

从useEffect依赖项中删除用户,因为您希望在组件装载时获取用户,而不是每次用户更改时

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中进行提取,它将更改用户,从而重新触发钩子,钩子将再次提取用户,从而更改用户并导致钩子重新触发-->这是一个无限循环

更新: 为什么当state.users的值相同时,useffect检测到此代码中的state.users会发生更改? 每当调度GET_USERS操作时,reducer都会返回新状态{…state,USERS:action.payload},即使action.payload的值与USERS的值相同,它也会这样做。 这就是useEffect接收新用户阵列的原因。他们做了肤浅的比较

注意,[1,2,3]不等于[1,2,3],即,[1,2,3]=[1,2,3]返回false


如果出于某种原因,您希望返回相同的redux状态,请在reducer中执行returnstate。这通常是我们在减速器切换的默认情况下所做的。

谢谢@Ajeet这解决了问题。但是,我需要一些关于用户状态的附加说明。从用户组件的角度来看,state.Users与每个后续重新触发器的值相同。我还没有更新或删除任何用户。也许我不太了解Redux状态。请在我的回复中查看更新谢谢@Ajeet这解决了问题。但是,我需要一些关于用户状态的附加说明。从用户组件的角度来看,state.Users与每个后续重新触发器的值相同。我还没有更新或删除任何用户。也许我不是很了解Redux状态。请在我的回答中检查更新