Egghead.io Redux Tutorial - Lesson 17: "TypeError: Unable to read property 'map' from undefined

I am following the egghead.io tutorial on Redux. I'm in lesson 17 and I'm wrong that Dan Abramov is not. The code is below.

The error I am getting is

"TypeError: Cannot read property 'map' of undefined

From my point of view I am getting the error because when I process the TodoApp it tries to render on top this.props.todos

which is empty. However, it doesn't get any errors?

What am I doing wrong?

const todo = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        id:action.id,
        text: action.text,
        completed: false
      }

    case 'TOGGLE_TODO':
      if (state.id !== action.id) {
        return state;
      }

      return {
        ...state,
        completed: !state.completed
      };

    default:
      return state
  }
}

const todos = (state = [], action) => {
  switch(action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        todo(undefined, action)
      ];

    case 'TOGGLE_TODO':
      return state.map(t => todo(t, action))  

    default:
      return state;
  }
};

const visbilityFilter = (
  state = 'SHOW_ALL',
  action
) => {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter;
    default:
      return state;
  }
}

const { combineReducers } = Redux
const todoApp = combineReducers({
  todos,
  visbilityFilter
});

const { createStore } = Redux;
const store = createStore(todos);

const { Component } = React;

let nextTodoId = 0

class TodoApp extends Component {
  render() {
    return (
      <div>
        <button onClick = {() => {
          store.dispatch({
            type: 'ADD_TODO', 
            text: 'Test', 
            id: nextTodoId++
          })
        }}>
          Add Todo
        </button>
        <ul>
          {this.props.todos.map(todo =>
            <li key={todo.id}>
              {todo.text}
            </li>
          )}
        </ul>
      </div>

    )
  }
}

const render = () => {
  ReactDOM.render(
    <TodoApp todos={store.getState().todos} />,
    document.getElementById('root')
  )
};

store.subscribe(render);

render()

      

+3


source to share


1 answer


You have combined your gearboxes, but you are building your store with gearbox only todos

, not combined.



const todoApp = combineReducers({
  todos,
  visbilityFilter
});

const { createStore } = Redux;
const store = createStore(todos); // <--- should be `todoApp`

      

+2


source







All Articles