Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript err: must have a '[Symbol.iterator]()' method that returns an iterator when using react usereducer hook in context-why?

Im using typescript, not too familiar with and am getting the following err for when I use context and useReducer hook- in particularly for my dispatch method I get this:

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

I tried to research it but can't figure out what to do. I imagine its because of const [state, dispatch] = useContext(GlobalState); and I need to specify something because of the array. Also, Im getting a ts err for value in

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

(see in code below). Somehow when I have it an array, all properties I have defined in ContextProps are missing. Any help would be so helpful!

//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>
  );
};
like image 830
javascripting Avatar asked Aug 17 '26 10:08

javascripting


1 Answers

There seem to be a few things wrong with the code you've provided.

First off, I would start by adding more typings.
Especially to the parameters and output of reducer and to the const [state, dispatch] = useReducer(reducer, initialState); (note: I assume that reducer was meant to be lowercase here, eventhough it's Reducer in your code sample.

Next, I think there is a problem with the definition of your context compared to how you're using it.
If you want to provide both the state and dispatch to your Provider (as indicated by <GlobalState.Provider value={[state, dispatch]}>, then I would expect your context definition to look more like this:

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

Note, that:

  • Your provider would change to: <GlobalState.Provider value={{state, dispatch}}>.
  • The usage would change to: const {state, dispatch} = useContext(GlobalState);

If you do want to use [state, dispatch] as the output of your context, then you should use a type like type Context = [{show: boolean; posts: string[];}, React.Dispatch<any>] instead of an interface.

Finally, an error like ... must have a '[Symbol.iterator]()' method that returns an iterator. usually means that you're iterating (using for, while, ...) through an object that isn't a type that can be iterated. An example of a type that can be iterated would be an Array.
If you'd like more guidance on this last error, then it would help if you specified exactly where this error is occuring.

like image 87
Stanislas Avatar answered Aug 19 '26 02:08

Stanislas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!