Todo

你有想过,为什么todo demo这么受欢迎吗? 因为它涉及到数据的增删改查,组件化等方方面面。 在学习redux的过程中,对于单一data flow,todo是个完美的例子,我们会在接下来的实例中一点点完善我们的todo,并引入相关概念与API。

主要功能

  1. 输入框输入内容,点击按钮添加todoItem并展示
  2. 点击todoItem,todoItem被标记为completed,表现为文字出现横划线
  3. 点击切换按钮可以查看不同状态下的todoItem,分别为:ALL, ACTIVE, COMPLETED

接下来我们将从最基本的功能实现起,至于为什么不一步到位,在下面的例子中会进行解释,相信你会明白这样的好处。

I. Implement basic & rough reducer of todos
  • 考虑到state里的第一项将是存放所有todoItem的Array,其初始状态应该是一个empty array.
  • Action type: 根据功能可知,我们会涉及的action有: 'ADDTODO' 'TOGGLE_TODO‘
/** 
* todos -> reducer
* @param [Array] array for todoItems
* @param [Object] action for operate todoItem
* @return [Array] the result of updated state
*/
const todos = (state = [], action) => { // Initial state will be an empty array
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...[state],
        {
          id: action.id,
          text: action.text,
          completed: false
        }
      ]
    case 'TOGGLE_TODO':
      return state.map( t => t.id === action.id ? 
          {...t, completed: !action.completed} : t)
    default:
      return state
  }    
}
II. Implement Todo component && createStore

由于我们已经实现过,这里我们直接使用redux提供的createStore.

const { createStore } = Redux

const store = createStore(todos)
/**
* Todo -> Component
* @param [String] text, content of todoItems
* @param [Boolean] status, decide which state to show
*/

const Todo = ({text, status}) => (
  <div style={{border: '1px solid #ccc', display: 'inline-block', padding: 10, margin: 10}} >
    <p style={{margin: 0}}>{`content: ${content}`}</p>
    <p style={{margin: 0}}>{`status: ${status}`}</p>
  </div>
)
III. Implement render function && subscribe render to store
const render = () => {
  ReactDOM.render(
    <div>
      {store.getState().map( todo => {
        let status = todo.completed ? 'yes' : 'no'
        return (
          <div>
            <Todo
              key={todo.id}
              content={todo.text}
              status={status}
            />
          </div>
        )
      })}
    </div>
    ,
    document.getElementById('root')
  )
}

store.subscribe(render)
IV. dispatch action
store.dispatch({
  type: 'ADD_TODO',
  id: 0,
  text: 'Learn React'
})

store.dispatch({
  type: 'ADD_TODO',
  id: 1,
  text: 'Learn Redux'
})

store.dispatch({
  type: 'ADD_TODO',
  id: 2,
  text: 'Learn React-Router'
})
看看效果:

JSBin

测试一下toggle:

store.dispatch({
    type: 'TOGGLE_TODO',
    id: 0
})

results matching ""

    No results matching ""