Skip to content

Commit

Permalink
Change altState and send the components state and props so static f…
Browse files Browse the repository at this point in the history
…unctions can be used
  • Loading branch information
Jeroen van der Heijden committed Sep 12, 2018
1 parent e938694 commit 3d0e67e
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 45 deletions.
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ this.mapStores([
keys: ['foo', 'status']
}, {
store: StoreFour,
altState: state => state
altState: storeState, state, props => storeState
}
]);
```
Expand All @@ -248,31 +248,35 @@ class MyComponent extends Vlow.Component.extend(React.PureComponent) {
}
```


### Using altState
Sometimes you want to listen to state changes in a store but then do something
with this state instead of just applying the state to a component.
This can be done by using an `altState(state)` hook which
will be triggered on state changes in the store but before the component state
This can be done by using an `altState(storeState, state, props)` hook which
will be triggered on state changes in the store but *before* the component state
is changed. The `altState` function should return the state changes you want to
make or `null` in case you don't want to update the state of the component.
```javascript
this.mapStore({store: ExampleStore, alState: (state) => {
// The `state` is received from the store. This is not the
// components state. This function should return the state
// you want to apply on `this` component. The function can
function altState(storeState, state, props) {
// This function should return the state
// you want to apply on the component. The function can
// also return `null` in which case the components state
// will not be changed.
if (this.props.status === 'error') {
if (props.status === 'error') {
// the components state will not be changed
return null;
}
// Return some alternative state for `this` component.
// Other components still receive the `original` state
// from the store.
return {
items: state.items.filter(i => i.age > this.state.minAge)
items: storeState.items.filter(i => i.age > state.minAge)
};
}});
}

// Use the altState function
const stores = {
store: MyStore,
altState,
};
```

2 changes: 1 addition & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ var _withVlow = _interopRequireDefault(require("./withVlow"));
* SOFTWARE.
*/
var Vlow = {
version: '1.1.2'
version: '1.1.4'
};
Vlow.Store = _store.default;
Vlow.Component = _component.default;
Expand Down
5 changes: 2 additions & 3 deletions lib/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,10 @@ function () {
}, {
key: "_vlowSetState",
value: function _vlowSetState(listener, state, counter) {
state = !listener.keys ? !listener.altState ? state : listener.altState(this.state) || {} : this._vlowFilterState(state, listener.keys);
var component = listener.component;
state = !listener.keys ? !listener.altState ? state : listener.altState(this.state, component.state, component.props) || {} : this._vlowFilterState(state, listener.keys);

if (Object.keys(state).length) {
var component = listener.component;

switch (component._vlowState_) {
case _states.default.init:
counter ? process.env.NODE_ENV !== 'production' ? (0, _invariant.default)(false, 'Store `%s` is using `setState()` with a callback on component `%s` which is not yet mounted. This is not possible, make sure all components are mounted or remove the callback from setState.', this.constructor.name, component.constructor.name) : (0, _invariant.default)(false) : undefined;
Expand Down
30 changes: 8 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vlow",
"version": "1.1.3",
"version": "1.1.4",
"description": "A simple library for unidirectional dataflow architecture inspired by Reflux",
"main": "lib/index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {createActions} from './actions';
import withVlow from './withVlow';

const Vlow = {
version: '1.1.2',
version: '1.1.4',
};

Vlow.Store = Store;
Expand Down
4 changes: 2 additions & 2 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ class Store {
}

_vlowSetState(listener, state, counter) {
state = !listener.keys ? !listener.altState ? state : listener.altState(this.state) || {} : this._vlowFilterState(state, listener.keys);
const component = listener.component;
state = !listener.keys ? !listener.altState ? state : listener.altState(this.state, component.state, component.props) || {} : this._vlowFilterState(state, listener.keys);

if (Object.keys(state).length) {
const component = listener.component;
switch (component._vlowState_) {
case States.init:
counter ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Store `%s` is using `setState()` with a callback on component `%s` which is not yet mounted. This is not possible, make sure all components are mounted or remove the callback from setState.', this.constructor.name, component.constructor.name) : invariant(false) : undefined;
Expand Down
10 changes: 6 additions & 4 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,12 @@ describe('Test alter state', () => {
class Component extends Vlow.Component.extend(FakeReactComponent) {
constructor(props) {
super(props);
this.mapStore({store: TestStore, altState: (state) => {
return !state ? null : {
items: state.items,
len: state.items.length
this.mapStore({store: TestStore, altState: (storeState, state, props) => {
assert(state === this.state, '`state` must be equal to the components state.');
assert(props === this.props, '`props` must be equal to the components props.');
return !storeState ? null : {
items: storeState.items,
len: storeState.items.length
};
}});
}
Expand Down

0 comments on commit 3d0e67e

Please sign in to comment.