|
|
@@ -2,7 +2,7 @@ import Calendar from '../Calendar'
|
|
|
import View from '../View'
|
|
|
import Theme from '../theme/Theme'
|
|
|
import { DateEnv } from '../datelib/env'
|
|
|
-import { isPropsEqual, assignTo, EqualityFuncHash } from '../util/object'
|
|
|
+import { assignTo } from '../util/object'
|
|
|
|
|
|
let guid = 0
|
|
|
|
|
|
@@ -14,12 +14,14 @@ export interface ComponentContext {
|
|
|
view?: View
|
|
|
}
|
|
|
|
|
|
+export type EqualityFuncHash = { [propName: string]: (obj0, obj1) => boolean }
|
|
|
+
|
|
|
export default class Component<PropsType> {
|
|
|
|
|
|
- equalityFuncs: EqualityFuncHash
|
|
|
+ equalityFuncs: EqualityFuncHash // can't initialize here. done below...
|
|
|
|
|
|
uid: string
|
|
|
- props: PropsType | null // non-null signals that a render happened
|
|
|
+ props: PropsType | null
|
|
|
|
|
|
// context vars
|
|
|
context: ComponentContext
|
|
|
@@ -52,9 +54,12 @@ export default class Component<PropsType> {
|
|
|
}
|
|
|
|
|
|
receiveProps(props: PropsType) {
|
|
|
- if (!this.props || !isPropsEqual(this.props, props, this.equalityFuncs)) {
|
|
|
- this.props = props
|
|
|
- this.render(props)
|
|
|
+ let { anyChanges, comboProps } = recycleProps(this.props || {}, props, this.equalityFuncs)
|
|
|
+
|
|
|
+ this.props = comboProps
|
|
|
+
|
|
|
+ if (anyChanges) {
|
|
|
+ this.render(comboProps)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -66,3 +71,39 @@ export default class Component<PropsType> {
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+Component.prototype.equalityFuncs = {}
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+Reuses old values when equal. If anything is unequal, returns newProps as-is.
|
|
|
+Great for PureComponent, but won't be feasible with React, so just eliminate and use React's DOM diffing.
|
|
|
+*/
|
|
|
+function recycleProps(oldProps, newProps, equalityFuncs: EqualityFuncHash) {
|
|
|
+ let comboProps = {} as any // some old, some new
|
|
|
+ let anyChanges = false
|
|
|
+
|
|
|
+ for (let key in newProps) {
|
|
|
+ if (
|
|
|
+ key in oldProps && (
|
|
|
+ oldProps[key] === newProps[key] ||
|
|
|
+ (equalityFuncs[key] && equalityFuncs[key](oldProps[key], newProps[key]))
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ // equal to old? use old prop
|
|
|
+ comboProps[key] = oldProps[key]
|
|
|
+ } else {
|
|
|
+ comboProps[key] = newProps[key]
|
|
|
+ anyChanges = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let key in oldProps) {
|
|
|
+ if (!(key in newProps)) {
|
|
|
+ anyChanges = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return { anyChanges, comboProps }
|
|
|
+}
|