繁体   English   中英

React redux 减速器作为 UseEffect 依赖导致无限循环

[英]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 switchdefault情况下所做的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM