From bbe949af9b9fb87658b515e23b579af3d6461876 Mon Sep 17 00:00:00 2001 From: Nicolas Deveaud Date: Thu, 7 Dec 2017 17:08:12 +0100 Subject: [PATCH 1/2] Remove useless wrapActionCreators --- src/connector.js | 7 ++++--- src/utils/index.js | 4 +--- src/utils/wrapActionCreators.js | 7 ------- 3 files changed, 5 insertions(+), 13 deletions(-) delete mode 100644 src/utils/wrapActionCreators.js diff --git a/src/connector.js b/src/connector.js index 8923f48..0faa501 100644 --- a/src/connector.js +++ b/src/connector.js @@ -1,7 +1,8 @@ +import { bindActionCreators } from 'redux' + import { shallowEqual, - wrapActionCreators -} from './utils/index' +} from './utils' const defaultMapState = () => ({}) const defaultMapDispatch = {} @@ -35,7 +36,7 @@ const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch const initData = {} const mapData = { ...mapState(this.$$store.getState()), - ...wrapActionCreators(mapDispatch)(this.$$store.dispatch) + ...bindActionCreators(mapDispatch, this.$$store.dispatch) } Object.keys(mapData).forEach(key => { diff --git a/src/utils/index.js b/src/utils/index.js index 0218e35..29549a6 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,7 +1,5 @@ import shallowEqual from './shallowEqual' -import wrapActionCreators from './wrapActionCreators' export { - shallowEqual, - wrapActionCreators + shallowEqual } diff --git a/src/utils/wrapActionCreators.js b/src/utils/wrapActionCreators.js deleted file mode 100644 index 1dfea7e..0000000 --- a/src/utils/wrapActionCreators.js +++ /dev/null @@ -1,7 +0,0 @@ -import { - bindActionCreators -} from 'redux' - -const wrapActionCreators = (actionCreators) => dispatch => bindActionCreators(actionCreators, dispatch) - -export default wrapActionCreators From ddba5b250f12099c01b82e2c3d3580208367a8be Mon Sep 17 00:00:00 2001 From: Nicolas Deveaud Date: Thu, 7 Dec 2017 17:08:36 +0100 Subject: [PATCH 2/2] Add support for event dispatch binding --- README.md | 7 ++++++ dist/revux.js | 21 ++++++++++++------ src/connector.js | 13 +++++++++-- test/connector.spec.js | 49 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0fa117d..50c3fdb 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,9 @@ Here our state looks something like `{ status: 'foobar' }` methods: { doMagic: function () { this.createAction() + }, + doMagic2: function () { + this.$emit('customevent') } } } @@ -103,6 +106,10 @@ Here our state looks something like `{ status: 'foobar' }` const mapDispatch = { createAction } + const mapEventDispatch = { + customevent: createAction + } + export default connect(mapState, mapDispatch)(component) ``` diff --git a/dist/revux.js b/dist/revux.js index de93738..df9a384 100644 --- a/dist/revux.js +++ b/dist/revux.js @@ -68,18 +68,19 @@ function shallowEqual(objA, objB) { return true; } -var wrapActionCreators = function wrapActionCreators(actionCreators) { - return function (dispatch) { - return redux.bindActionCreators(actionCreators, dispatch); - }; -}; - var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var defaultMapState = function defaultMapState() { return {}; }; var defaultMapDispatch = {}; +var defaultEventDispatch = {}; + +var forEach = function forEach(obj, iterator) { + return Object.keys(obj).forEach(function (key) { + return iterator(key, obj[key]); + }); +}; var normalizeMapState = function normalizeMapState(mapState) { if (typeof mapState === 'function') { @@ -103,6 +104,7 @@ var connector = function connector() { var _mapState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultMapState; var mapDispatch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultMapDispatch; + var eventDispatch = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultEventDispatch; return function (component) { var mapState = normalizeMapState(_mapState); return { @@ -112,7 +114,7 @@ var connector = function connector() { data: function data() { var initData = {}; - var mapData = _extends({}, mapState(this.$$store.getState()), wrapActionCreators(mapDispatch)(this.$$store.dispatch)); + var mapData = _extends({}, mapState(this.$$store.getState()), redux.bindActionCreators(mapDispatch, this.$$store.dispatch)); Object.keys(mapData).forEach(function (key) { initData[key] = mapData[key]; @@ -124,6 +126,11 @@ var connector = function connector() { var _this = this; var vm = this; + + forEach(redux.bindActionCreators(eventDispatch, this.$$store.dispatch), function (eventName, dispatcher) { + return vm.$on(eventName, dispatcher); + }); + var getMappedState = function getMappedState(state) { return mapState(state); }; diff --git a/src/connector.js b/src/connector.js index 0faa501..2e8688f 100644 --- a/src/connector.js +++ b/src/connector.js @@ -2,10 +2,13 @@ import { bindActionCreators } from 'redux' import { shallowEqual, -} from './utils' +} from './utils/index' const defaultMapState = () => ({}) const defaultMapDispatch = {} +const defaultEventDispatch = {} + +const forEach = (obj, iterator) => Object.keys(obj).forEach(key => iterator(key, obj[key])) const normalizeMapState = mapState => { if (typeof mapState === 'function') { @@ -25,7 +28,7 @@ const normalizeMapState = mapState => { } } -const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch) => component => { +const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch, eventDispatch = defaultEventDispatch) => component => { const mapState = normalizeMapState(_mapState); return { name: `connect-${component.name}`, @@ -48,6 +51,12 @@ const connector = (_mapState = defaultMapState, mapDispatch = defaultMapDispatch created () { const vm = this + + forEach( + bindActionCreators(eventDispatch, this.$$store.dispatch), + (eventName, dispatcher) => vm.$on(eventName, dispatcher) + ) + const getMappedState = state => mapState(state) const observeStore = (store, select, onChange) => { diff --git a/test/connector.spec.js b/test/connector.spec.js index d6bf273..2948f64 100644 --- a/test/connector.spec.js +++ b/test/connector.spec.js @@ -181,6 +181,55 @@ describe('Connector', () => { }) + describe('events mapping', () => { + let dispatchStub + const originalDispatch = store.dispatch + beforeEach(() => { + dispatchStub = sinon.stub().returns() + store.dispatch = dispatchStub + }) + + afterEach(() => { + store.dispatch = originalDispatch + }) + + it('should map actions on events on connected component', () => { + let vm + let actionCreator = sinon.stub().returns({type: 'DO_THIS'}); + + const baseComponent = { + created () { + vm = this + }, + render () {} + } + + const mapEvents = { + eventName: actionCreator + } + + new Vue({ + template: ``, + provide: { + $$store: store + }, + components: { + connected: { + template: ``, + components: { + connectedComponent: connector(undefined, undefined, mapEvents)(baseComponent) + } + } + } + }).$mount() + + vm.$emit('eventName'); + + expect(actionCreator.called, 'action creator was not called').to.be.true + expect(store.dispatch.called, 'dispatch was not called').to.be.true + }) + }) + it('should override and use mapDispatch value if the same key is defined both in mapState and mapDispatch', () => { let vm const baseComponent = {