前言
使用 react, redux 開發一個應用是非常複雜的,moox 是基於 redux 的高效能狀態管理機,簡化了 redux 模板程式碼和提高了效率,本篇教程將帶領大家在五分鐘時間做一個 todomvc 應用。 當然,本篇教程不包括 react 環境搭建,推薦使用新的打包工具 Parcel
注:parcel 需要 node > 8.0
效果圖
原始碼地址:demo
起步
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 元件。
model.js
import moox from '../src/index'
import user from './models/user'
export default moox({
user
})
複製程式碼
Model 是通過 moox(Object) 生成的物件。
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)} <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 應用。