2017-06-19 5 views
0

このエラーが発生していますが、その理由がわかりません。私はステップを逃したと仮定しています。私は何度かレッスンを終わりましたが、私が間違ったことを理解することはできません。Egghead Reduxチュートリアル:レッスン19

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

コードは以下のとおりです。私は私の理解では、store.getState()が渡され、その後visibleTodosとエラーを作成してオーバーマップされていることがvisibleTodos.map(todo => ...)

TodoApp下.MAP機能を参照していると思います。そうですか?

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 {は小道具として、コンポーネントストアのデータを与えるものである、あなたのReduxの店に@connect編ではありません。そして、あなたは

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

呼び出すしかし、あなたが店にあなたのコンポーネントを接続していないので、小道具は空になり、そしてあなたは、空の引数を指定してgetVisibleTodosを呼んでいます。

あなたのTodoAppコンポーネントは、チュートリアルのビデオで完全に説明されているconnect() (or use decorator @connect)コンポーネントにする必要があります。あなたは間違ってそれを飛ばしたかもしれません。

+0

'store.subscribe(render)'は接続していませんか? –

+0

おっと、私はその行を逃した! –

0

スペルミスで、VisibilityFilterとなりました!