Reputation: 956
I am a newbie in React and making a todo application using it. For listing the todos entered by the user, I am trying to use the map to go through all the todos and have added a functionality to be able to remove any of the todos.
Here is my Todos.js
:
import React, {useContext} from 'react';
import {ListGroup, ListGroupItem} from 'reactstrap';
import {FaCheckDouble} from 'react-icons/fa';
import { TodoContext } from '../Context/TodoContext';
import { REMOVE_TODO } from '../Context/action.types';
const Todos = () => {
const {todos, dispatch} = useContext(TodoContext);
return(
<ListGroup className="mt-5 mb-2 items">
{todos.map(todo => (
<ListGroupItem key={todo.id}>
{todo.todoString}
<span
className="float-right"
onClick={() => {
dispatch({
type: REMOVE_TODO,
payload: todo.id
})
}}
><FaCheckDouble/></span>
</ListGroupItem>
))}
</ListGroup>
)
}
export default Todos;
And here is my App.js
(Updated todo
to todos
)
import React, {useReducer} from 'react';
import Container from "reactstrap/lib/Container";
import "bootstrap/dist/css/bootstrap.min.css";
import './App.css';
import {TodoContext} from './Context/TodoContext';
import todoReducer from "./Context/reducer";
import TodoForm from './Component/TodoForm';
import Todos from './Component/Todos';
const App = () => {
const [todos, dispatch] = useReducer(todoReducer, [])
return(
<TodoContext.Provider value={{todos, dispatch}}>
<Container fluid>
<h1>
Todo App with Context API
</h1>
<Todos/>
<TodoForm/>
</Container>
</TodoContext.Provider>
)
}
export default App;
The browser is throwing me the error: TypeError: Cannot read property 'map' of undefined
Upvotes: 0
Views: 235
Reputation: 19
This is a very common issue with React. Todos value is initially undefined, and you're trying to render it. You can check its value with useEffect().
You should do the following:
const Todos = () => {
const {todos, dispatch} = useContext(TodoContext);
return(
<ListGroup className="mt-5 mb-2 items">
{todos ? (
{todos.map(todo => (
<ListGroupItem key={todo.id}>
{todo.todoString}
<span
className="float-right"
onClick={() => {
dispatch({
type: REMOVE_TODO,
payload: todo.id
})
}}>
<FaCheckDouble/>
</span>
</ListGroupItem>
))}
) : null}
</ListGroup>
)}
What you are basically saying is: if todos has some value, render the todos.map, if not, render nothing.
Hope this helps you.
Upvotes: 1
Reputation: 355
Please ensure that todos
is an array and not undefined. undefined.map()
obviously does not make sense. So make sure that is imported properly and you can actually do like todos && todos.map()
.
Upvotes: 1