React - useContext is returning undefined

321 Views Asked by At

I trying to use React context to manage state in my project, but I cannot seem to figure out why it's returning undefined. I copied the example from another project I was working on, and it seems as if everything should be working properly. I just can't seem to pin down why it is not.

Here is where I am creating the context.

import React, { useState } from "react";

const initialTodos = [
  {
    id: 1,
    title: "Setup development environment",
    completed: true,
  },
  {
    id: 2,
    title: "Develop website and add content",
    completed: false,
  },
  {
    id: 3,
    title: "Deploy to live server",
    completed: false,
  },
];

export const TodoContext = React.createContext({
  todos: initialTodos,
  onChange: () => {},
});

const TodoContextProvider = (props) => {
  const [todos, setTodos] = useState(initialTodos);

  const handleChange = () => {
    console.log("clicked");
  };

  return (
    <TodoContext.Provider value={{ todos: todos, onChange: handleChange }}>
      {props.children}
    </TodoContext.Provider>
  );
};

export default TodoContextProvider;

Here is where I am wrapping the app.

import React from "react";
import ReactDOM from "react-dom";

import TodoContainer from "./components/TodoContainer";
import TodoContextProvider from "./context/TodoContext";

ReactDOM.render(
  <TodoContextProvider>
    <TodoContainer />
  </TodoContextProvider>,
  document.getElementById("root")
);

Here is my TodoContainer.

import React, { useContext } from "react";
import TodosList from "./TodosList";
import Header from "./Header";
import TodoContext from "../context/TodoContext";

const TodoContainer = (props) => {
  const todoContext = useContext(TodoContext);

  console.log("todoContext", todoContext);

  return (
    <div>
      <Header />
      <TodosList />
    </div>
  );
};

export default TodoContainer;

And here is where I am attempting to use the context.

import React, { useContext } from "react";
import TodoItem from "./TodoItem";
import TodoContext from "../context/TodoContext";

const TodosList = (props) => {
  const todoContext = useContext(TodoContext);

  console.log(todoContext);

  return (
    <div>
      {todoContext.todos.map((todo) => (
        <TodoItem key={todo.id} todo={todo.title} />
      ))}
    </div>
  );
};

export default TodosList;

Finally, here is the error I receive.

TypeError: Cannot read property 'todos' of undefined
TodosList
C:/Users/Stacey/repos/simple-todo-app/src/components/TodosList.js:11
   8 |  console.log(todoContext);
   9 | 
  10 |  return (
> 11 |    <div>
     | ^  12 |      {todoContext.todos.map((todo) => (
  13 |        <TodoItem key={todo.id} todo={todo.title} />
  14 |      ))}

1

There are 1 best solutions below

1
On BEST ANSWER

You are importing the TodoContext as a default import but it must be a named import.

change in the TodosList.js:

import TodoContext from "../context/TodoContext";

to:

import { TodoContext } from "../context/TodoContext";

and it will work