zoukankan      html  css  js  c++  java
  • [Redux] React Todo List Example (Filtering Todos)

    /**
     * A reducer for a single todo
     * @param state
     * @param action
     * @returns {*}
     */
    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;
        }
    };
    
    /**
     * The reducer for the todos
     * @param state
     * @param action
     * @returns {*}
     */
    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;
    
        }
    };
    
    /**
     * Reducer for the visibilityFilter
     * @param state
     * @param action
     * @returns {*}
     */
    const visibilityFilter = ( state = 'SHOW_ALL',
                               action ) => {
        switch ( action.type ) {
            case 'SET_VISIBILITY_FILTER':
                return action.filter;
            default:
                return state;
        }
    };
    
    
    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
          );
      }
    }
    
    /**
     * combineReducers: used for merge reducers togethger
     * createStore: create a redux store
     */
    const { combineReducers, createStore } = Redux;
    const todoApp = combineReducers( {
        todos,
        visibilityFilter
    } );
    
    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>
      );
    };
    
    /**
     * For generate todo's id
     * @type {number}
     */
    let nextTodoId = 0;
    
    /**
     * React related
     */
    const {Component} = React;
    class TodoApp extends Component {
        render() {
          
          const {todos, visibilityFilter} = this.props;
          let visibleTodos = getVisibleTodos(todos, visibilityFilter);
          
            return (
                <div>
                    <input ref={
            (node)=>{
                this.input = node
            }
        }/>
                    <button onClick={
            ()=>{
            //After clicking the button, dispatch a add todo action
                store.dispatch({
                    type: 'ADD_TODO',
                    id: nextTodoId++,
                    text: this.input.value
                })
                this.input.value = "";
            }
        }>ADD todo
                    </button>
                    <ul>
                        {visibleTodos.map( ( todo )=> {
                            return (
                                <li key={todo.id}
                                    style={{
                                     textDecoration: todo.completed ?
                                     'line-through' : 'none'
                                    }}
    
                                    onClick={ ()=>{
                                       store.dispatch({
                                       type: 'TOGGLE_TODO',
                                       id: todo.id
                                      })
                                    }}
                                >
                                    {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>
            );
        }
    }
    
    const render = () => {
        ReactDOM.render(
            <TodoApp {...store.getState()}/>,
            document.getElementById( 'root' )
        );
    };
    
    //Every time, store updated, also fire the render() function
    store.subscribe( render );
    render();
  • 相关阅读:
    mongodb性能测试:long时间戳与string格式时间
    .netcore mongodb 分页+模糊查询+多条件查询
    .netcore 图片处理
    ELEMENT-UI 封装el-table 局部刷新row
    vue-upload 封装组件-上传组件
    vue实现v-model父子组件间的双向通信
    cc.AudioSource
    Chrome插件:本地程序实现验证码破解(浏览器与本地进程通信)
    Chrome插件:微信公众号自动登录(chrome.extension)
    Chrome插件:浏览器后台与页面间通信
  • 原文地址:https://www.cnblogs.com/Answer1215/p/5133697.html
Copyright © 2011-2022 走看看