Comparing version 1.0.2 to 1.1.0
36
index.js
@@ -1,2 +0,2 @@ | ||
import {autorun} from 'mobx'; | ||
import {reaction} from 'mobx'; | ||
@@ -12,11 +12,33 @@ exports.observer = observer; | ||
target.render = (component, setState) => { | ||
let result; | ||
let baseRender = _render(component, setState); | ||
if (unsubscriber) { | ||
unsubscriber(); | ||
} | ||
unsubscriber = autorun(() => { | ||
result = _render(component, setState); | ||
setState({ __updates: updateCount++ }); | ||
}); | ||
return result; | ||
// Get all of the mobx stores from props | ||
const stores = Object.keys(component.props).map((prop) => { | ||
const property = component.props[prop]; | ||
if (typeof property === 'object' && property.hasOwnProperty('$mobx')) { | ||
return property; | ||
} | ||
}).filter((prop) => prop); | ||
unsubscriber = reaction( | ||
() => { | ||
// Extract the obvserables | ||
const observables = stores.map((store) => { | ||
if (!store) return {}; | ||
Object.keys(store).map((prop) => { | ||
return store[prop]; | ||
}); | ||
}); | ||
return observables; | ||
}, | ||
(observables) => { | ||
_render(component, setState); | ||
setState({ __updates: updateCount++ }); | ||
}) | ||
; | ||
return baseRender; | ||
}; | ||
@@ -23,0 +45,0 @@ |
'use strict'; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
var _mobx = require('mobx'); | ||
@@ -14,11 +16,32 @@ | ||
target.render = function (component, setState) { | ||
var result = void 0; | ||
var baseRender = _render(component, setState); | ||
if (unsubscriber) { | ||
unsubscriber(); | ||
} | ||
unsubscriber = (0, _mobx.autorun)(function () { | ||
result = _render(component, setState); | ||
// Get all of the mobx stores from props | ||
var stores = Object.keys(component.props).map(function (prop) { | ||
var property = component.props[prop]; | ||
if ((typeof property === 'undefined' ? 'undefined' : _typeof(property)) === 'object' && property.hasOwnProperty('$mobx')) { | ||
return property; | ||
} | ||
}).filter(function (prop) { | ||
return prop; | ||
}); | ||
unsubscriber = (0, _mobx.reaction)(function () { | ||
// Extract the obvserables | ||
var observables = stores.map(function (store) { | ||
if (!store) return {}; | ||
Object.keys(store).map(function (prop) { | ||
return store[prop]; | ||
}); | ||
}); | ||
return observables; | ||
}, function (observables) { | ||
_render(component, setState); | ||
setState({ __updates: updateCount++ }); | ||
}); | ||
return result; | ||
return baseRender; | ||
}; | ||
@@ -25,0 +48,0 @@ |
{ | ||
"name": "mobx-deku", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "mobx bindings for deku", | ||
@@ -10,2 +10,3 @@ "main": "lib/index.js", | ||
"build": "babel index.js --out-dir lib", | ||
"watch": "babel index.js -w --out-dir lib", | ||
"prepublish": "npm run clean && npm run build" | ||
@@ -55,4 +56,5 @@ }, | ||
"semistandard": { | ||
"parser": "babel-eslint" | ||
"parser": "babel-eslint", | ||
"ignore": "/lib" | ||
} | ||
} |
# mobx-deku | ||
mobx bindings for deku | ||
Package with deku component wrapper for combining deku with mobx. Exports the observer function decorator. For documentation, see the [mobx](https://github.com/mobxjs/mobx) project. | ||
`npm install mobx-deku` | ||
# Example | ||
## Boilerplate Projects that use mobx-deku | ||
* Minimal MobX, deku, ES6, JSX, Hot reloading: [mobx-deku-boilerplate](https://github.com/orrybaram/mobx-deku-boilerplate) | ||
## API documentation | ||
### observer(component) | ||
Function that converts a Deku component definition or stand-alone render function into a reactive component. | ||
See the [mobx](https://mobxjs.github.io/mobx/refguide/observer-component.html) documentation for more details. | ||
```javascript | ||
import {observer} from "mobx-deku"; | ||
const TodoView = observer({ | ||
render({props}) { | ||
return <div>{props.todo.title}</div> | ||
} | ||
})); | ||
``` | ||
## Full Example | ||
```js | ||
@@ -24,4 +45,6 @@ import {render, tree} from 'deku'; | ||
return ( | ||
<div class='app'>{props.appState.counter}</div> | ||
<button onClick={onClick}></button> | ||
<div> | ||
<div class='app'>{props.appState.counter}</div> | ||
<button onClick={onClick}>+</button> | ||
</div> | ||
); | ||
@@ -37,2 +60,2 @@ function onClick () { | ||
Special thanks to @mattmccray and https://gist.github.com/mattmccray/d8740ea97013c7505a9b | ||
Special thanks to [mobx-react](https://github.com/mobxjs/mobx-react/blob/master/index.js) and [@mattmccray's gist](https://gist.github.com/mattmccray/d8740ea97013c7505a9b) |
@@ -13,3 +13,12 @@ import {render, tree} from 'deku'; | ||
} | ||
class AppState2 { | ||
@observable counter = 0; | ||
increaseCounter () { | ||
this.counter += 1; | ||
} | ||
} | ||
const appState = new AppState(); | ||
const appState2 = new AppState2(); | ||
@@ -19,3 +28,6 @@ const App = observer({ | ||
return ( | ||
<div class='app'>{props.appState.counter}</div> | ||
<div> | ||
<div class='app'>{props.appState.counter}</div> | ||
<div class='app2'>{props.appState2.counter}</div> | ||
</div> | ||
); | ||
@@ -26,3 +38,3 @@ } | ||
const container = document.createElement('div'); | ||
const app = render(tree(<App appState={appState} />), container); | ||
const app = render(tree(<App appState={appState} appState2={appState2} />), container); | ||
@@ -48,1 +60,16 @@ test('App gets rendered', (t) => { | ||
}); | ||
test.cb('App UI gets updated when data changes in the second store', (t) => { | ||
var $app = container.querySelector('.app2'); | ||
t.is($app.innerHTML, '0', 'Default value at 0'); | ||
appState2.increaseCounter(); | ||
setTimeout(() => { | ||
t.is($app.innerHTML, '1', 'Updates to 1'); | ||
appState2.counter = 10; | ||
}); | ||
setTimeout(() => { | ||
t.is($app.innerHTML, '10', 'updates to 10'); | ||
t.end(); | ||
}, 100); | ||
}); |
9455
201
59