@@ -8,8 +8,6 @@ import js.lib.Object;
88
99using tink .CoreApi ;
1010
11- private typedef Render = Lazy <RenderResult >;// without this some part of the react component macro seems to hang
12-
1311@:build (coconut.ui.macros. ViewBuilder .build ((_ : coconut.react. RenderResult )))
1412@:autoBuild (coconut.react. View .autoBuild ())
1513class View extends ViewBase {
@@ -21,14 +19,13 @@ class View extends ViewBase {
2119 return (cast react .React .createElement ).apply (null , [react. Fragment , attr ].concat (cast children ));
2220}
2321
24- class ViewBase extends NativeComponent <{ vtree : Render }, {}, ImplicitContext > {
22+ class ViewBase extends NativeComponent <{ vtree : RenderResult }, {}, ImplicitContext > {
2523
2624 @:noCompletion var __rendered : Observable <RenderResult >;
27- @:noCompletion var __link : CallbackLink ;
25+ @:noCompletion var __binding : Binding ;
2826 @:noCompletion var __viewMounted : Void -> Void ;
2927 @:noCompletion var __viewUpdated : Void -> Void ;
3028 @:noCompletion var __viewUnmounting : Void -> Void ;
31- @:noCompletion var __rewrapped : RenderResult ;
3229
3330 public function new (
3431 rendered : Observable <RenderResult >,
@@ -37,31 +34,46 @@ class ViewBase extends NativeComponent<{ vtree: Render }, {}, ImplicitContext> {
3734 unmounting : Void -> Void
3835 ) {
3936 js. Syntax .code (' {0}.call(this)' , NativeComponent );
37+ this .__rendered = rendered ;
4038 this .__react_state = __snap ();
41-
42- __rendered = rendered ;
43-
4439 this .__viewMounted = mounted ;
4540 this .__viewUpdated = updated ;
4641 this .__viewUnmounting = unmounting ;
4742 }
4843
49- @:noCompletion function __snap (): { vtree : Render }
50- return { vtree : function () return __rendered .value };
44+ @:noCompletion function __snap (): { vtree : RenderResult }
45+ return { vtree : Observable . untracked (() -> __rendered .value ) };
5146
5247 @:keep @:noCompletion @:final function componentDidMount () {
53- __link = __rendered .bind (function (_ ) __react_setState (__snap ()));// not my most glorious moment ... a better solution would probably be to poll in render and forceUpdate when becameInvalid
5448 if (__viewMounted != null ) __viewMounted ();
5549 }
5650
5751 @:keep @:noCompletion @:final function componentDidUpdate (_ , _ )
5852 if (__viewUpdated != null ) __viewUpdated ();
5953
6054 @:keep @:noCompletion @:final function componentWillUnmount () {
61- __link .cancel ();
55+ switch __binding {
56+ case null :
57+ case v :
58+ __binding = null ;
59+ v .destroy ();
60+ }
6261 if (__viewUnmounting != null ) __viewUnmounting ();
6362 }
6463
64+ @:keep @:noCompletion @:final function shouldComponentUpdate (_ , next : { vtree : RenderResult })
65+ return __react_state .vtree != next .vtree ;
66+
67+ @:keep @:noCompletion @:final @:native (' render' ) function reactRender () {
68+ if (this .__binding == null ) {
69+ this .__binding = new Binding (this );
70+ }
71+ return switch this .__react_state .vtree {
72+ case js. Syntax .typeof (_ ) => ' undefined' : null ;
73+ case v : v ;
74+ }
75+ }
76+
6577 static function __init__ () {
6678 #if react_devtools
6779 Object .defineProperty (untyped ViewBase .prototype , ' state' , {
@@ -127,13 +139,23 @@ class ViewBase extends NativeComponent<{ vtree: Render }, {}, ImplicitContext> {
127139 }
128140 });
129141 }
142+ }
130143
131- @:keep @:noCompletion @:final function shouldComponentUpdate (_ , next : { vtree : Render })
132- return __react_state .vtree .get () != next .vtree .get ();
144+ private class Binding {
133145
134- @:keep @:noCompletion @:final @:native (' render' ) function reactRender ()
135- return switch this .__react_state .vtree .get () {
136- case js. Syntax .typeof (_ ) => ' undefined' : null ;
137- case v : v ;
138- }
146+ final target : ViewBase ;
147+ final link : CallbackLink ;
148+
149+ public function new (target ) @:privateAccess {
150+ this .target = target ;
151+ this .link = target .__rendered .bind (_ -> target .__react_setState (target .__snap ()));
152+ }
153+
154+ public function destroy ()
155+ this .link .cancel ();
156+
157+ #if tink_state.debug
158+ @:keep function toString (): String
159+ return ' Binding' ;
160+ #end
139161}
0 commit comments