Kaynağa Gözat

remove subrender method. equality funcs

Adam Shaw 7 yıl önce
ebeveyn
işleme
70b48fe22c
3 değiştirilmiş dosya ile 27 ekleme ve 44 silme
  1. 12 42
      src/component/Component.ts
  2. 1 0
      src/exports.ts
  3. 14 2
      src/util/object.ts

+ 12 - 42
src/component/Component.ts

@@ -2,8 +2,7 @@ import Calendar from '../Calendar'
 import View from '../View'
 import Theme from '../theme/Theme'
 import { DateEnv } from '../datelib/env'
-import { isArraysEqual } from '../util/array'
-import { isPropsEqual } from '../util/object'
+import { isPropsEqual, assignTo, EqualityFuncHash } from '../util/object'
 
 let guid = 0
 
@@ -17,12 +16,10 @@ export interface ComponentContext {
 
 export default class Component<PropsType> {
 
-  uid: string
+  equalityFuncs: EqualityFuncHash
 
+  uid: string
   props: PropsType | null // non-null signals that a render happened
-  renderArgs: { [renderMethodName: string]: any[] } = {} // also indicates if rendered
-  renderIds: { [renderMethodName: string]: number } = {}
-  unrenderMethodNames: Map<string, string> = new Map()
 
   // context vars
   context: ComponentContext
@@ -42,12 +39,20 @@ export default class Component<PropsType> {
     this.isRtl = this.opt('dir') === 'rtl'
   }
 
+  static addEqualityFuncs(newFuncs: EqualityFuncHash) {
+    this.prototype.equalityFuncs = assignTo(
+      {},
+      this.prototype.equalityFuncs,
+      newFuncs
+    )
+  }
+
   opt(name) {
     return this.context.options[name]
   }
 
   receiveProps(props: PropsType) {
-    if (!this.props || !isPropsEqual(this.props, props)) {
+    if (!this.props || !isPropsEqual(this.props, props, this.equalityFuncs)) {
 
       if (this.props) {
         this.unrender()
@@ -64,46 +69,11 @@ export default class Component<PropsType> {
   protected unrender() {
   }
 
-  subrender(renderMethodName, args, unrenderMethodName?): number {
-    let { renderIds, renderArgs } = this
-    let prevArgs = renderArgs[renderMethodName]
-    let renderId = renderIds[renderMethodName]
-
-    if (!prevArgs || !isArraysEqual(prevArgs, args)) {
-
-      if (prevArgs && unrenderMethodName) {
-        this[unrenderMethodName].apply(this, prevArgs)
-      }
-
-      this[renderMethodName].apply(this, args)
-      renderArgs[renderMethodName] = args
-      renderIds[renderMethodName] = renderId = guid++
-
-      // for destroy
-      if (unrenderMethodName) {
-        this.unrenderMethodNames.set(renderMethodName, unrenderMethodName)
-      }
-    }
-
-    return renderId
-  }
-
   // after destroy is called, this component won't ever be used again
   destroy() {
-    let { renderArgs } = this
-
     if (this.props) {
       this.unrender()
     }
-
-    let tuples = [] // in reverse
-    this.unrenderMethodNames.forEach(function(unrenderMethodName, renderMethodName) {
-      tuples.unshift([ unrenderMethodName, renderMethodName ])
-    })
-
-    for (let tuple of tuples) {
-      this[tuple[0]].apply(this, renderArgs[tuple[1]])
-    }
   }
 
 }

+ 1 - 0
src/exports.ts

@@ -37,6 +37,7 @@ export {
 } from './util/array'
 
 export { default as reselector } from './util/reselector'
+export { memoizeRendering } from './component/memoized-rendering'
 
 export {
   intersectRects

+ 14 - 2
src/util/object.ts

@@ -117,9 +117,21 @@ export function arrayToHash(a): { [key: string]: true } {
 }
 
 
-export function isPropsEqual(obj0, obj1): boolean {
+export type EqualityFuncHash = { [propName: string]: (obj0, obj1) => boolean }
+
+export function isPropsEqual(obj0, obj1, equalities: EqualityFuncHash = {}): boolean {
   for (let key in obj0) {
-    if (obj0[key] !== obj1[key]) {
+    let val0 = obj0[key]
+    let val1 = obj1[key]
+
+    if (
+      val0 !== val1 &&
+      !(
+        equalities[key] &&
+        val1 !== undefined && // we already know val0 exists
+        equalities[key](val0, val1)
+      )
+    ) {
       return false
     }
   }