用 react+moox 五分鐘寫一個 todomvc 應用

前言

使用 react, redux 開發一個應用是很是複雜的,moox 是基於 redux 的高性能狀態管理機,簡化了 redux 模板代碼和提升了效率,本篇教程將帶領你們在五分鐘時間作一個 todomvc 應用。 固然,本篇教程不包括 react 環境搭建,推薦使用新的打包工具 Parcelnode

注:parcel 須要 node > 8.0react

效果圖

源碼地址:demo git

起步

npm install --save moox
npm install --save react-redux
複製代碼

目錄結構

components/App.js
models/user.js
index.js
model.js
複製代碼

入口文件 index.js

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import App from './components/App'
import Model from './model'

const store = Model.getStore()
render(
  <Provider store={store}> <App /> </Provider>,
  document.getElementById('root')
)

複製代碼

store 經過 getStore 方法獲取,傳給 Provider 組件。github

model.js

import moox from '../src/index'
import user from './models/user'

export default moox({
  user
})

複製代碼

Model 是經過 moox(Object) 生成的對象。npm

userModel 文件 user.js

export default {
  // 初始化 state
  state: {
    list: ['tom', 'xiaoming'],
    status: 0,
    filterText: ''
  },
  // 帶Action 後綴的字符串表明一個 action函數
  addUserSyncAction: null,
  requestStatusAction: null,
  changeFilterValueAction: (text)=>({
    text
  }),
  changeCurrentEditUserAction: (name, index) =>({
    name,
    index
  }),
  addUserAction: () => (
    {
      payload: new Promise((resolve) => {
        setTimeout(function () {
          resolve(100)
        }, 300)
      })
    }
  ),
  delUserAction: (index)=>{
    return {
      index: index
    }
  },  
  // 在 reducers 對象裏寫對應 action 的 state 處理函數,參數經過 action 對象獲取。
  reducers: {
    changeCurrentEditUserAction: function(state, action){
      state.list[action.index] = action.name
    },
    changeFilterValueAction: function(state, action){
      state.filterText = action.text
    },
    changeEditIndexAction: function(state, action){
      state.currentEditIndex = action.index
    },
    addUserAction: function (state, action) {
      state.list.push(getRandomName())
      state.status = 0
    },
    addUserSyncAction: function(state, action){
      state.list.push(getRandomName(5))
    },
    requestStatusAction: function (state, action) {
      state.status = 1
    },
    delUserAction: function(state, action){
      state.list.splice(action.index, 1)
    }
  }
}

function getRandomName(len=4){
  let str = ''
  while(len--) str += String.fromCharCode(97 + Math.ceil(Math.random()* 25))
  return str
}

複製代碼

組件 App.js

import React from 'react'
import { connect } from 'react-redux'
import Model from '../model'

const App = (props) => {
  const handleClick = () => {
    if (props.user.status === 1) return;
    props.requestStatusAction()
    props.addUserAction()
  }
  const handleClickSync = () => props.addUserSyncAction()
  const delUser = (index) => ()=>props.delUserAction(index)
  const getContent = (item, index) => {
    return <input type="text" onChange={(event) => {
      props.changeCurrentEditUserAction(event.target.value, index)
    }} value={item} />
  }
  const list = props.user.list.filter(item=>{
    item = item + '';
    return !props.user.filterText || item.indexOf(props.user.filterText) !== -1
  })

  return <div style={{ width: 500, margin: '100px auto' }}>
    <div >
      <input placeholder="Filter" style={{height: 35, width: '100%', backgroundColor: '#eee'}} type="text" value={props.user.filterText} onChange={(event)=> props.changeFilterValueAction(event.target.value)} />
    </div>
    <div>
      <button style={{ height: '40px', margin: 30 }} onClick={handleClick}>Async Add Random Number</button>
      <button style={{ height: '40px', margin: 30 }} onClick={handleClickSync}>Add Random Number</button>
      {props.user.status === 1 ? 'loading...' : ''}
    </div>
    {list.map((item, index) => {
      return <div style={{ height: 30, margin: 15, backgroundColor: '#eee' }} key={index}>{}{getContent(item, index)} &nbsp; <span onClick={delUser(index)}>X</span></div>
    })}
  </div>
}
export default connect((state) => ({
  user: state.user
}), {
    addUserAction: Model.user.addUserAction,
    requestStatusAction: Model.user.requestStatusAction,
    delUserAction: Model.user.delUserAction,
    addUserSyncAction: Model.user.addUserSyncAction,
    changeCurrentEditUserAction: Model.user.changeCurrentEditUserAction,
    changeFilterValueAction: Model.user.changeFilterValueAction
  })(App)
複製代碼

到這裏,咱們已經完成了一個簡單的 todomvc 應用。redux

相關文章
相關標籤/搜索