Brian
Brian

Reputation: 187

React JS passing prop to be mapped

I am trying to turn my mega-class into smaller reusable components, however, I am stuck on passing prop names to be mapped. The first code-block is my mega-class, I am trying to break it into smaller components shown in my second code block, but an error is give when I try to use props.categoryName.map in the second code block. How else should I approach this?

// Sort todos by due date. Completed todos get moved to completed list.
    let today = todos.filter(todo => todo.date === "today" && !todo.complete)
    let completedTodos = todos.filter(todo => todo.complete)

    return (
        <div className="td-app">
            <TodoForm onSubmit={this.addTodo}/>

            {/* <Category categoryName="today"/> */}

            <div className="td-section">
                <div className="td-category">
                    <h2 className="today">Today</h2>
                    
                    <p className="td-count">{todayTodos.length} todos</p>
                </div>
                <div className="td-list">
                        {todayTodos.map(todo => (
                                <Todo 
                                    key={todo.id} 
                                    toggleComplete={() => this.toggleComplete(todo.id)} 
                                    onDelete={() => this.handleDeleteTodo(todo.id)}
                                    todo={todo}
                                />
                        ))}
                </div>
            </div>

My component class is here:

import React from 'react'
import Todo from './Todo'

const Category = (props) => (
    <div className="td-section">
        <div className="td-category">
            <h2 className={props.categoryName}>{props.categoryName}</h2>
            
            <p className="td-count">{props.categoryName.length} todos</p>
        </div>
        <div className="td-list">
                {props.categoryName.map(todo => (
                        <Todo 
                            key={todo.id} 
                            toggleComplete={() => this.toggleComplete(todo.id)} 
                            onDelete={() => this.handleDeleteTodo(todo.id)}
                            todo={todo}
                        />
                ))}
        </div>
    </div>
)
export default Category

Upvotes: 0

Views: 38

Answers (1)

trixn
trixn

Reputation: 16309

You passed categoryName as the string literal "today". As that obviously is not an array of todos you can't call .map() on it. If you also want to map over your todos inside of your Category component you also have to pass the todos. Note that you actually have to pass the list as the prop not a string with the name of the variable that holds it:

<Category 
    categoryName="today" 
    todos={today} 
    onComplete={this.toggleComplete} 
    onDelete={this.handleDeleteTodo}
/>

and .map() over it in your component:

const Category = ({categoryName, todos, onComplete, onDelete}) => (
    <div className="td-section">
        <div className="td-category">
            <h2 className={categoryName}>{categoryName}</h2>
            
            <p className="td-count">{todos.length} todos</p>
        </div>
        <div className="td-list">
                {todos.map(todo => (
                    <Todo 
                        key={todo.id} 
                        toggleComplete={() => onComplete(todo.id)} 
                        onDelete={() => onDelete(todo.id)}
                        todo={todo}
                    />
                ))}
        </div>
    </div>
)

Upvotes: 2

Related Questions