2017-06-19 78 views
0

我得到這個錯誤,我不知道爲什麼。我假設我錯過了一步。我已經讀了幾遍,但無法弄清楚我做錯了什麼。Egghead Redux教程:第19課

"error" 
"TypeError: Cannot read property 'map' of undefined 
    at TodoApp.render (xuwuwoqaso.js:157:23) 

代碼如下。我認爲它是指。TodoApp下的.map函數與visibleTodos.map(todo => ...)

據我所知,store.getState()被傳入然後映射到visibleTodos並創建錯誤。是對的嗎?

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(todoApp); 
const { Component } = React; 

const FilterLink = ({ 
    filter, 
    children 
}) => { 
    return (
    <a href='#' 
     onClick={e => { 
     e.preventDefault(); 
     store.dispatch({ 
      type: 'SET_VISIBILITY_FILTER', 
      filter 
     }); 
     }} 
    > 
     {children} 
    </a> 
); 
}; 

const getVisibleTodos = (
    todos, 
    filter 
) => { 
    switch (filter) { 
    case 'SHOW_ALL': 
     return todos; 
    case 'SHOW_COMPLETED': 
     return todos.filter(
     t => t.completed 
    ); 
    case 'SHOW_ACTIVE': 
     return todos.filter(
     t => !t.completed 
    ); 
    } 
} 

let nextTodoId = 0 

class TodoApp extends Component { 
    render() { 
    const visibleTodos = getVisibleTodos(
     this.props.todos, 
     this.props.visibilityFilter 
    ); 
    return (
     <div> 
     <input ref ={node => { 
      this.input = node; 
     }} /> 

     <button onClick = {() => { 
      store.dispatch({ 
      type: 'ADD_TODO', 
      text: this.input.value, 
      id: nextTodoId++ 
      }); 
      this.input.value = '' 
     }}> 
      Add Todo 
     </button> 
     <ul> 
      {visibleTodos.map(todo => 
      <li key={todo.id} 
       onClick={() => { 
        store.dispatch({ 
        type:'TOGGLE_TODO', 
        id:todo.id 
        }); 
       }} 
       style = {{ 
        textDecoration: 
        todo.completed ? 
         'line-through' : 
         'none' 
       }}> 
       {todo.text} 
      </li> 
     )} 
     </ul> 
     <p> 
      Show: 
      {' '} 
      <FilterLink filter='SHOW_ALL'>All</FilterLink> 
      {' '} 
      <FilterLink filter='SHOW_ACTIVE'>Active</FilterLink> 
      {' '} 
      <FilterLink filter='SHOW_COMPLETED'>Completed</FilterLink> 
      {' '} 
     </p> 
     </div> 

    ) 
    } 
} 

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

store.subscribe(render); 

render() 

回答

0

class TodoApp extends Component {@connect編輯您Redux的商店,這是什麼讓您的組件存儲數據的道具。然後調用

const visibleTodos = getVisibleTodos(
    this.props.todos, 
    this.props.visibilityFilter 
); 

但因爲你還沒有連接您的組件商店,道具將是空的,而你正在與空參數調用getVisibleTodos

您需要connect() (or use decorator @connect)您的TodoApp組件,這在教程視頻中已有完整的介紹。您可能意外跳過了它。

+0

不會'store.subscribe(render)'連接它嗎? –

+0

哎呀,我錯過了那一行! –

0

這是一個拼寫錯誤VisibilityFilter woops!