TypeScript错误:在使用React useReducer钩子时,在上下文中必须有一个返回迭代器的[Symbol.iterator]()方法-为什么?

3

我正在使用TypeScript,对其不是很熟悉,当我使用context和useReducer hook时,出现了以下错误,特别是对于我的dispatch方法,我获得了以下错误:

contextProps must have a '[Symbol.iterator]()' method that returns an iterator.

我试图进行研究,但无法弄清楚该做什么。我想这是由于const [state, dispatch] = useContext(GlobalState);,并且我需要指定某些内容,因为涉及到数组。 此外,我在value处遇到了ts错误。

  <GlobalState.Provider value={[state, dispatch]}>

(请见下面的代码)。当我将它定义为数组时,ContextProps 中定义的所有属性都消失了。 希望能得到帮助!

//context.js file
export interface ProjectProps {
  projects: string[]
}

export interface ContextProps extends ProjectProps {
  show: boolean
  posts: string[]
  //...
}

const initialState = {
  posts: [],
  show: false
  //...
};

export const GlobalState = React.createContext<ContextProps | null>(
  initialState
)

const reducer = (state, action) => {
  switch (action.type) {
    case "SHOW":
      return { ...state, show: !state.show }

    default:
      return state
  }
}

const Store: React.FC<{ children: React.ReactNode }> = ({children}) => {
  const [state, dispatch] = useReducer(Reducer, initialState);
  return (
      <GlobalState.Provider value={[state, dispatch]}>
          {children}
      </GlobalState.Provider>
  )
};


const App = () => {
  return (
      <Store>
          <Header/>
          <Blog/>
      </Store>
  );
};

const Blog = () => {

  const [state, dispatch] = useContext(GlobalState);

  return (
      <div>
        <button onClick={dispatch({type: "SHOW"})}></button>
        {state.show ? <p>hello</p> : null }
      </div>
  );
};
1个回答

3

你提供的代码存在一些问题。

首先,我建议添加更多的类型定义。
特别是对于reducer函数的参数和输出以及对于const [state, dispatch] = useReducer(reducer, initialState);的定义(注意:尽管你的代码示例中是Reducer,但这里我假定它应该是小写的reducer)。

其次,我认为你的上下文定义与你的使用方法存在问题。
如果你想要在Provider中同时提供statedispatch(如<GlobalState.Provider value={[state, dispatch]}>所示),那么我期望你的上下文定义看起来更像这样:

interface Context {
  state: {
    show: boolean;
    posts: string[];
    //...
  };
  dispatch: React.Dispatch<any>; // I don't know what any should be in your case
}

注意:

  • 您的提供程序将更改为:<GlobalState.Provider value={{state, dispatch}}>
  • 使用方法将更改为:const {state, dispatch} = useContext(GlobalState);

如果您确实希望将[state, dispatch]用作上下文的输出,则应该使用类似于type Context = [{show: boolean; posts: string[];}, React.Dispatch<any>]这样的类型,而不是使用interface

最后,像...必须具有返回迭代器的'[Symbol.iterator]()'方法。这样的错误通常意味着您正在遍历(使用forwhile等)一个不能被迭代的对象。可迭代的类型示例包括Array
如果您需要更多关于此错误的指导,请指定发生此错误的确切位置。


谢谢。无论我在哪里使用上下文(--> const [state,dispatch] = useContext(GlobalState) 用于状态和/或调度),我都可以获得[Symbol.iterator]。此外,由于它与我的问题无关,我没有添加更多的键入,但是还是谢谢。我也尝试了您的上下文定义,但只给了我错误。 - javascripting
1
其实,现在我想起来了 const [state, dispatch] = useContext(GlobalState)。你在这里将一个数组解构成了两个变量。但是 GlobalState 的类型来自于 React.createContext<ContextProps | null>(initialState)。它不是一个数组,也不能被迭代。 - Stanislas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接