diff --git a/src/connect.js b/src/connect.js old mode 100644 new mode 100755 index 14904a9..9718afe --- a/src/connect.js +++ b/src/connect.js @@ -1,14 +1,16 @@ -import shallowEqual from './shallowEqual.js' +import stateDiff from './stateDiff.js' import warning from './warning.js' import wrapActionCreators from './wrapActionCreators.js' const defaultMapStateToProps = state => ({}) // eslint-disable-line no-unused-vars -const defaultMapDispatchToProps = dispatch => ({dispatch}) +const defaultMapDispatchToProps = dispatch => ({ + dispatch +}) function connect(mapStateToProps, mapDispatchToProps) { const shouldSubscribe = Boolean(mapStateToProps) const mapState = mapStateToProps || defaultMapStateToProps - const app = getApp(); + const app = getApp() let mapDispatch if (typeof mapDispatchToProps === 'function') { @@ -27,11 +29,17 @@ function connect(mapStateToProps, mapDispatchToProps) { } const state = this.store.getState() - const mappedState = mapState(state, options); - if (!this.data || shallowEqual(this.data, mappedState)) { - return; + const mappedState = mapState(state, options) + const { + __state + } = this + const patch = stateDiff(mappedState, __state) + if (!patch) { + return } - this.setData(mappedState) + this.__state = mappedState + // only pass in updated data to .setData() + this.setData(patch) } const { @@ -44,9 +52,12 @@ function connect(mapStateToProps, mapDispatchToProps) { if (!this.store) { warning("Store对象不存在!") } - if(shouldSubscribe){ - this.unsubscribe = this.store.subscribe(handleChange.bind(this, options)) - handleChange.apply(this) + if (shouldSubscribe) { + this.__state = {} + this.unsubscribe = this.store.subscribe(() => { + handleChange.call(this, options) + }) + handleChange.call(this) } if (typeof _onLoad === 'function') { _onLoad.call(this, options) @@ -54,14 +65,19 @@ function connect(mapStateToProps, mapDispatchToProps) { } function onUnload() { + typeof this.unsubscribe === 'function' && this.unsubscribe() + // should no long receive state changes after .onUnload() + this.unsubscribe = null if (typeof _onUnload === 'function') { _onUnload.call(this) } - typeof this.unsubscribe === 'function' && this.unsubscribe() } - return Object.assign({}, pageConfig, mapDispatch(app.store.dispatch), {onLoad, onUnload}) + return Object.assign({}, pageConfig, mapDispatch(app.store.dispatch), { + onLoad, + onUnload + }) } } -module.exports = connect \ No newline at end of file +module.exports = connect diff --git a/src/shallowEqual.js b/src/shallowEqual.js deleted file mode 100644 index 040c7a4..0000000 --- a/src/shallowEqual.js +++ /dev/null @@ -1,25 +0,0 @@ -function shallowEqual(objA, objB) { - if (objA === objB) { - return true - } - - const keysA = Object.keys(objA) - const keysB = Object.keys(objB) - - if (keysA.length !== keysB.length) { - return false - } - - // Test for A's keys different from B. - const hasOwn = Object.prototype.hasOwnProperty - for (let i = 0; i < keysA.length; i++) { - if (!hasOwn.call(objB, keysA[i]) || - objA[keysA[i]] !== objB[keysA[i]]) { - return false - } - } - - return true -} - -module.exports = shallowEqual \ No newline at end of file diff --git a/src/stateDiff.js b/src/stateDiff.js new file mode 100755 index 0000000..c3854a7 --- /dev/null +++ b/src/stateDiff.js @@ -0,0 +1,29 @@ +const hasOwn = Object.prototype.hasOwnProperty + +function stateDiff(nextState, state) { + if (nextState === state) { + return null + } + + const patch = {} + + const keys = Object.keys(nextState) + const length = keys.length + let hasChanged = false + for (let i = 0; i < length; ++i) { + const key = keys[i] + const val = nextState[key] + if (!hasOwn.call(state, key) || val !== state[key]) { + patch[key] = val + hasChanged = true + } + } + + if (!hasChanged) { + return null + } + + return patch +} + +module.exports = stateDiff