因此,我一直在通過Dan Abramov的Redux教程來構建一個簡單的待辦事項應用程序。下面是主要的渲染功能的代碼,爲什麼切換待辦事項在Redux中不起作用?
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 visibilityFilter = (state = 'SHOW_ALL', action) => {
switch(action.type){
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
const todoApp = combineReducers({
visibilityFilter,
todos
});
const store = createStore(todoApp);
const FilterLink = ({
filter,
currentFilter,
children
}) => {
if(filter === currentFilter){
return <span>{children}</span>
}
return (
<a href='#' onClick={e => {
e.preventDefault();
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter
})
}}>
{children}
</a>
)
}
const Todo = ({
onClick,
completed,
text
}) => (
<li onClick={(onClick)}
style={{textDecoration: completed ? 'line-through' : 'none'}}>
{text}
</li>
);
const TodoList = ({
todos,
onTodoClick
}) => (
<ul>
{todos.map(todo =>
<Todo key={todo.id} {...todo}
onClick={() => onTodoClick(todo.id)} />
)}
</ul>
);
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 React.Component {
render() {
const {
todos,
visibilityFilter
} = this.props
const visibleTodos = getVisibleTodos(todos, visibilityFilter);
return (
<div>
<input ref={text => {
this.input = text;
}} />
<button onClick={() => {
store.dispatch({
type:"ADD_TODO",
text: this.input.value,
id: nextTodoId++
});
this.input.value = '';
}}>Add a todo
</button>
<TodoList todos={visibleTodos} onTodoClick={id => store.dispatch({
type: 'TOGGLE_TODO',
id
})} />
<p>
Show:
{' '}
<FilterLink filter='SHOW_ALL' currentFilter={visibilityFilter}>
All
</FilterLink>
{' '}
<FilterLink filter='SHOW_COMPLETED' currentFilter={visibilityFilter}>
Completed
</FilterLink>
{' '}
<FilterLink filter='SHOW_ACTIVE' currentFilter={visibilityFilter}>
Active
</FilterLink>
</p>
</div>
)
}
}
const render =() => {
console.log(store.getState());
ReactDOM.render(<TodoApp {...store.getState()}/>, document.getElementById('root'));
}
store.subscribe(render);
render();
當我嘗試切換待辦事項,我得到以下錯誤,
index.js:170 Uncaught TypeError: Cannot read property 'id' of undefined
現在,當我試圖註銷this.props.todos在我嘗試切換待辦事項時,它返回未定義。這就是我得到錯誤的原因,因爲由於某些原因,this.props.todos沒有被傳遞給click事件。但是,我仔細閱讀了課程筆記,並且具有完全相同的代碼。我在這裏做錯了什麼?我該如何解決它?
你可以看到數據時,你CONSOLE.LOG(this.props.todos) –
是它在github? – abhirathore2006
所以,當它第一次渲染,然後我添加一個新的待辦事項,它工作正常。但是,當我點擊其中一個待辦事項以切換其完成狀態時,它會引發錯誤,此時this.props.todos日誌未定義。 –