[Redux] Extracting Presentational Components -- TodoApp

來源:互聯網
上載者:User

標籤:

Finally, I just noticed that the to-do app component doesn‘t actually have to be a class. I can turn it into a function. I prefer to-do that when possible.

Code to be refactored:

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>    );  }}

  

TO:

 

const TodoApp = ({  todos,  visibilityFilter}) => {  return (      <div>        <AddTodo            onAddTodo={ text =>              store.dispatch({                  type: ‘ADD_TODO‘,                  id: nextTodoId++,                  text              })           }        />        <TodoList           todos={getVisibleTodos(              todos,              visibilityFilter          )}          onTodoClick={            (id)=>{              store.dispatch({                type: ‘TOGGLE_TODO‘,                id              })            }          }        />        <Footer            visibilityFilter = {visibilityFilter}           onFilterClick={ (filter) => {              store.dispatch({                 type: ‘SET_VISIBILITY_FILTER‘,                 filter             });           }}        />      </div>    );}

 

 

---------------

All code:

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 { combineReducers } = Redux;const todoApp = combineReducers({  todos,  visibilityFilter});const { createStore } = Redux;const store = createStore(todoApp);const { Component } = React;/*PC*/const Todo = ({  text,  completed,  onTodoClick})=>{  return (    <li                 onClick={onTodoClick}                style={{                  textDecoration:                    completed ?                      ‘line-through‘ :                      ‘none‘                }}>              {text}            </li>  );}/*PC*/const TodoList = ({  todos,  onTodoClick}) => {  return (    <ul>          {todos.map(todo =>            <Todo              key={todo.id}             {...todo}             onClick={                ()=>{                  onTodoClick                }             }            />          )}        </ul>  );}/** Functional compoment, persental compoment: doesn‘t need to know what to do, just show the interface, call the callback function.*/const AddTodo = ({  onAddTodo}) => {    let input;  return (     <div>          <input ref={node => {          input = node;        }} />        <button onClick={() => {          onAddTodo(input.value);          input.value = ‘‘;        }}>          Add Todo        </button>     </div>  );}/* Functional component */const Footer = ({  visibilityFilter,  onFilterClick}) => (        <p>          Show:          {‘ ‘}          <FilterLink            filter=‘SHOW_ALL‘            currentFilter={visibilityFilter}            onFilterClick={onFilterClick}          >            All          </FilterLink>          {‘, ‘}          <FilterLink            filter=‘SHOW_ACTIVE‘            currentFilter={visibilityFilter}            onFilterClick={onFilterClick}          >            Active          </FilterLink>          {‘, ‘}          <FilterLink            filter=‘SHOW_COMPLETED‘            currentFilter={visibilityFilter}            onFilterClick={onFilterClick}          >            Completed          </FilterLink>        </p>);const FilterLink = ({  filter,  currentFilter,  children,  onFilterClick}) => {  if (filter === currentFilter) {    return <span>{children}</span>;  }  return (    <a href=‘#‘       onClick={e => {         e.preventDefault();         onFilterClick(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;const TodoApp = ({  todos,  visibilityFilter}) => {  return (      <div>        <AddTodo            onAddTodo={ text =>              store.dispatch({                  type: ‘ADD_TODO‘,                  id: nextTodoId++,                  text              })           }        />        <TodoList           todos={getVisibleTodos(              todos,              visibilityFilter          )}          onTodoClick={            (id)=>{              store.dispatch({                type: ‘TOGGLE_TODO‘,                id              })            }          }        />        <Footer            visibilityFilter = {visibilityFilter}           onFilterClick={ (filter) => {              store.dispatch({                 type: ‘SET_VISIBILITY_FILTER‘,                 filter             });           }}        />      </div>    );}const render = () => {  ReactDOM.render(    <TodoApp      {...store.getState()}    />,    document.getElementById(‘root‘)  );};store.subscribe(render);render();

 

[Redux] Extracting Presentational Components -- TodoApp

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.