用 React Actions Recorder 作为 Store 写 Todolist
关于研究 Redux 之后还是自己从头实现了一套方案出来 近几天配合简聊做了一些调整,于是针对新的版本( 下面是 希望对不喜欢 Redux 的同学能有帮助 Store简聊的应用中,除了 View 和网络相关代码以外,大致可以分成几个部分:
随后是处理页面初次加载的代码,将这些部分组合起来 对于 Todolist 这部分会比较简单,按照顺序依次创建文件 # schema.coffee Immutable = require 'immutable' exports.store = Immutable.fromJS [] exports.task = Immutable.fromJS id: null text: '' done: false Updater 是定义 Store 如何更新的函数,类似数据库的 Query Language # updater/index.coffee todo = require './todo' module.exports = (store,actionType,actionData) -> switch actionType when 'todo/create' todo.create store,actionData when 'todo/update' todo.update store,actionData when 'todo/toggle' todo.toggle store,actionData when 'todo/archive' todo.archive store,actionData else store Updater 目录当中的其他文件用来写具体的数据库如何更新的逻辑 # updater/todo.coffee schema = require '../schema' exports.create = (store,id) -> store.push schema.task.set('id',id) exports.update = (store,actionData) -> id = actionData.get('id') text = actionData.get('text') store.map (task) -> if task.get('id') is id task.set 'text',text else task exports.toggle = (store,id) -> store.map (task) -> if task.get('id') is id task.update 'done',(status) -> not status else task exports.archive = (store) -> store.filterNot (task) -> task.get('done') 然后是 Actions,或者说 Actions Creator,用来生成 Actions # actions.coffee shortid = require 'shortid' recorder = require 'actions-recorder' exports.create = -> recorder.dispatch 'todo/create',shortid.generate() exports.update = (id,text) -> recorder.dispatch 'todo/update',{id,text} exports.toggle = (id) -> recorder.dispatch 'todo/toggle',id exports.archive = -> recorder.dispatch 'todo/archive',id 完成了上边几个组件的代码,最后就可以用初始化代码开始做整合了 # main.coffee React = require 'react' recorder = require 'actions-recorder' ReactDOM = require 'react-dom' Immutable = require 'immutable' updater = require './updater' require('volubile-ui/ui/index.less') Page = React.createFactory require './app/page' recorder.setup initial: Immutable.List() updater: updater render = (store,core) -> ReactDOM.render Page({store,core}),document.querySelector('.demo') recorder.request render recorder.subscribe render 这样,基本的 Todolist 的数据流就整合完成了 Node 环境执行另外注意有些情况页面需要在 Node 环境渲染,也是可以支持的 # template.coffee stir = require 'stir-template' React = require 'react' ReactDOM = require 'react-dom/server' recorder = require 'actions-recorder' Immutable = require 'immutable' Page = React.createFactory require './src/app/page' {html,head,title,body,meta,script,link,div,a,span} = stir line = (text) -> div class: 'line',text module.exports = (data) -> recorder.setup initial: Immutable.List() stir.render stir.doctype(),html null,head null,title null,"Todolist in actions-recorder" meta charset: 'utf-8' link rel: 'icon' href: 'http://tp4.sinaimg.cn/5592259015/180/5725970590/1' link rel: 'stylesheet' href: if data.dev then 'src/main.css' else data.style script src: data.vendor,defer: true script src: data.main,defer: true body null,div class: 'demo',recorder.request (store,core) -> ReactDOM.renderToString Page({store,core}) DevToolsDevTools 主要的功能是 Actions 的重演和 Store 的查看 # part of app/page.coffee React = require 'react' Immutable = require 'immutable' Devtools = React.createFactory require 'actions-recorder/lib/devtools' Todolist = React.createFactory require './todolist' updater = require '../updater' div = React.createFactory 'div' module.exports = React.createClass displayName: 'app-page' propTypes: store: React.PropTypes.instanceOf(Immutable.List).isRequired core: React.PropTypes.object.isRequired renderDevtools: -> core = @props.core if typeof window is 'undefined' width = 600 height = 400 else width = window.innerWidth * 0.6 height = window.innerHeight Devtools store: @props.store updater: updater initial: core.initial pointer: core.pointer isTravelling: core.isTravelling records: core.records width: width height: height render: -> div style: @styleRoot(),Todolist tasks: @props.store @renderDevtools() 注意这里的 另外关于调试工具的使用,我说明一下 DevTools 实际上生成的是个 DevTools 跟 Redux 一样是单独的组件,所以自己可以随意开发的 优劣我自己不能公允地评价一遍大,大致说一下我的看法
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |