Code to be refactored:
let nextTodoId = 0; class TodoApp extends Component { render() { const { todos, visibilityFilter } = this.props; const visibleTodos = getVisibleTodos( todos, 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' currentFilter={visibilityFilter} > All </FilterLink> {', '} <FilterLink filter='SHOW_ACTIVE' currentFilter={visibilityFilter} > Active </FilterLink> {', '} <FilterLink filter='SHOW_COMPLETED' currentFilter={visibilityFilter} > Completed </FilterLink> </p> </div> ); } }
First extact a single Todo as a persental component: which doesn't know what to do, just response for showing the interface:
So it accept a callback function to the onClick handler:
//remove onClick={() => { store.dispatch({ type: 'TOGGLE_TODO', id: todo.id }); }} ------------- // replace onClick={onTodoClick}
const Todo = ({ text, completed, onTodoClick })=>{ return ( <li onClick={onTodoClick} style={{ textDecoration: completed ? 'line-through' : 'none' }}> {text} </li> ); }
TodoList, should also be a persentional component:
const TodoList = ({ todos, onTodoClick }) => { return ( <ul> {todos.map(todo => <Todo key={todo.id} {...todo} onClick={ ()=>{ onTodoClick } } /> )} </ul> ); }
The TodoApp is the 'contianer component' which tell 'persentional componet' what to display and the action to dispatch.
class TodoApp extends Component { render() { const { todos, visibilityFilter } = this.props; const visibleTodos = getVisibleTodos( todos, visibilityFilter ); return ( <div> <AddTodo onAddTodo={ text => store.dispatch({ type: 'ADD_TODO', id: nextTodoId++, text }) } /> <TodoList todos={visibleTodos} onTodoClick={ (id)=>{ store.dispatch({ type: 'TOGGLE_TODO', id }) } } /> <Footer visibilityFilter = {visibilityFilter} onFilterClick={ (filter) => { store.dispatch({ type: 'SET_VISIBILITY_FILTER', filter }); }} /> </div> ); } }
in a word:
Presentaional compnent doesn't need to know what to do, only response for display.
Container component dispatch the action, and pass down to the persentional component.
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。