react js undefined is not iterable (cannot read property Symbol(Symbol.iterator)) error

3.1k Views Asked by At

so i am trying to make a to-do app with react and i just tried using Context and i keep getting undefined is not iterable:

this is Main/index.js:

import React,{useContext} from "react";
import { BrowserRouter as Router,Routes, Route, Link} from 'react-router-dom';
import {GlobalContext} from "../Context/provider.js"
import TodoForm from "../Todo-Form/index.js"
import Description from "../Description/index.js"
import "./style.css";

export default function Main () {

const {todos, setTodos} = useContext(GlobalContext);

const addTodo = text => {
    const newTodos = [...todos, { text }];
    setTodos(newTodos);
};

const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].isCompleted = newTodos[index].isCompleted ? false : true;
    setTodos(newTodos);
};

this is Context/provider.js:

import React from "react";
   import { useState,createContext } from "react";

   export const GlobalContext = createContext()

  export  const ContextProvider = ({children})=> {
    const [todos, setTodos] = useState([
        {
          text: "You can write your to-do above and add",
          isCompleted: false,
          description: "hello",
          id:0
        },
    ]);
    return(
       <GlobalContext.Provider value = {{todos, setTodos}} >
            {children}
       </GlobalContext.Provider>
    )
}

EDİT SOLVED !! aside from my problem with: const {todos, setTodos} = useContext(GlobalContext); it turns out i havent wrapped with provider so when i did this in app.js it worked :

<ContextProvider>
  <div className="main-div">
    <Header />
    <Main />
  </div>

</ContextProvider>

thanks for everyone who took a look and provided some solutions.

2

There are 2 best solutions below

2
dmc85 On BEST ANSWER

The problem might be here: const [todos, setTodos] = useContext({GlobalContext});

Try putting const [todos, setTodos] = useContext(GlobalContext); (removing the brackets around GlobalContext) because you're passing an object with {GlobalContext: GlobalContext} instead of just passing the context as an argument.

In addition to this, there are couple of more issues that I see:

  1. The main one is that you need to wrap <Main /> with that you define in provider.js. Then you can put components within ContextProvider that can access the context.
  2. Fix the spelling error in the children prop in ContextProvider Here's a sandbox: https://codesandbox.io/s/shy-meadow-8gf0sd?file=/src/App.js
1
Arman On

The problem is that you are spearing an object inside an array. If your global context is an array you should set the value as follow:

const [todos, setTodos] = useContext(GlobalContext);

After that, you can iterate through todos.

In addition to this, there are couple of more issues that I see:

  1. The main is that you need to wrap with that you import from provider.js. Then you can put components within ContextProvider that can access the context.
  2. fix the spelling error in the children prop in ContextProvider

Here's a sandbox: https://codesandbox.io/s/shy-meadow-8gf0sd?file=/src/App.js