使用 useEffect 更新 useReducer 的“状态”

Posted

技术标签:

【中文标题】使用 useEffect 更新 useReducer 的“状态”【英文标题】:Updating useReducer 'state' using useEffect 【发布时间】:2020-06-07 09:37:44 【问题描述】:

在我的应用程序中,我使用的是 React Hooks/Context API。现在,每当我的 Provider 组件挂载时,我需要将从 localStorage 获取的数据分配给 initialState.carts / state.carts。如果 useEffect 支持返回对象,这是可能的。但是不能在useEffect中返回对象!

现在我该如何解决这个问题?

代码如下,

const initialState = 
  books: books,
  carts: []
;

export const Context = createContext(initialState);

export const Provider = ( children ) => 
  const [state, dispatch] = useReducer(reducer, initialState);

  useEffect(() => 
    if (localStorage.getItem("carts") !== null) 
      const fetchedCarts = JSON.parse(localStorage.getItem("carts"));
      //Here I want to assign 'fetchedCarts' array items in 'state.carts' or 'initialState.carts'
    
  );

【问题讨论】:

调度一个将state.carts设置为fetchedCarts的操作 【参考方案1】:

您必须调度一个操作来更新您的 state 变量。

if (localStorage.getItem("carts") !== null) 
      const fetchedCarts = JSON.parse(localStorage.getItem("carts"));
      dispatch( type: 'UPDATE', payload: fetchedCarts )

因此,您必须将此操作类型添加到您已在此处使用的 reducer 开关:

const [state, dispatch] = useReducer(reducer, initialState);

减速器结构示例:

const reducer = (state, action) => 
  switch (action.type) 
    case 'UPDATE':
      return  ...state, ...action.payload 
      break
    default:
      return state
  


我认为useEffect()应该有一个依赖数组(因为state的更新会以当前的形式重新触发)。

如果 useEffect 支持返回对象,这是可能的。但是不能在useEffect中返回对象!

useEffect 的响应应该是一个函数(该函数在组件被卸载之前被调用)——在这里返回一个对象是错误的。

【讨论】:

您可能还想添加一个带有空依赖项数组的useEffect 示例并将action.payload 分配给cart 而不是传播它 @Deykun 我做到了。但在 useEffect 中显示“QuotaExceededError:无法在 'Storage' 上执行 'setItem':设置 'carts' 的值超出了配额。”错误。如果我像你一样不使用 useEffect 来做;它显示“重新渲染过多。 React 限制渲染次数以防止无限循环':( @EbrahimKhalilAmid 1. 你在 localStorage.setItem 中做错了什么。 2. 正如上面提到的 Asaf,您可以使用 `useEffect( () => ... logic ... , [] ) 来实现 - 一个空数组只会触发一次该钩子,您不能直接放置该函数进入组件代码,因为它会在每次重新渲染时被调用,并且这个函数会导致重新渲染。

以上是关于使用 useEffect 更新 useReducer 的“状态”的主要内容,如果未能解决你的问题,请参考以下文章

了解函数化组件 HooksuseState,useEffect,useContext,useReducer

了解函数化组件 HooksuseState,useEffect,useContext,useReducer

React hooks之useEffect

在 React 中使用 useContext 和 useReducer 创建新的键值对

useEffect和useLayoutEffect

useReducer 和 useState