@@ -242,6 +242,98 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
242242 } ;
243243 } , [ ] ) ;
244244
245+ // memoized webview/view style to avoid recreating object on every render
246+ const memoizedContainerStyle = useMemo ( ( ) => {
247+ const base = style || { } ;
248+ return {
249+ ...base ,
250+ width : options ?. width || base ?. width || '100%' ,
251+ height : options ?. height || base ?. height || '100%' ,
252+ } ;
253+ } , [ style , options ?. width , options ?. height ] ) ;
254+
255+ // memoized onLoadEnd handler for native WebView
256+ const handleLoadEnd = useCallback ( ( ) : void => {
257+ // Use canonical dataRef when creating the native WebView chart
258+ dataRef . current = toPlainArrays ( data as any [ ] ) as number [ ] [ ] ;
259+ createChart ( options , dataRef . current , bgColor ) ;
260+
261+ if ( onLoad ) {
262+ onLoad ( ) ;
263+ }
264+ } , [ data , options , bgColor , onLoad ] ) ;
265+
266+ // memoized onMessage handler for native WebView
267+ const handleMessage = useCallback (
268+ ( payload : any ) : void => {
269+ if ( onMessage ) {
270+ onMessage ( payload ) ;
271+ return ;
272+ }
273+
274+ let dataPayload ;
275+ try {
276+ dataPayload = JSON . parse ( payload . nativeEvent . data ) ;
277+ } catch ( e ) { }
278+
279+ if ( dataPayload ) {
280+ if ( dataPayload . type === 'Console' ) {
281+ console . info ( `[Console] ${ JSON . stringify ( dataPayload . data ) } ` ) ;
282+ } else {
283+ console . log ( dataPayload ) ;
284+ }
285+ }
286+ } ,
287+ [ onMessage ] ,
288+ ) ;
289+
290+ // memoized ref callback for both web container and native WebView
291+ const setWebRef = useCallback (
292+ ( r : any ) => {
293+ const prevContainer = containerRef . current ;
294+ const prevWeb = webref . current ;
295+ const shouldReinit = Boolean ( prevContainer && r && r !== prevWeb ) ;
296+
297+ // update refs (allow clearing when r is null)
298+ containerRef . current = r ;
299+ webref . current = r ;
300+
301+ if ( ! r ) return ;
302+
303+ // On web, simply create chart when the DOM node appears
304+ if ( Platform . OS === 'web' ) {
305+ createChart ( options , data ) ;
306+ return ;
307+ }
308+
309+ // Native WebView: detect reinitialization and restore variables/data
310+ if ( shouldReinit ) {
311+ initialized . current = false ;
312+ destroy ( true ) ;
313+ }
314+
315+ if ( shouldReinit ) {
316+ // console.log('Reinitializing WebView chart');
317+
318+ // re-add any variables that were set
319+ let injectedVars = '' ;
320+ Object . keys ( variablesRef . current ) . forEach ( ( key ) => {
321+ injectedVars += `window.${ key } = ${ JSON . stringify (
322+ variablesRef . current [ key ] ,
323+ ) } ;`;
324+ } ) ;
325+ webref . current . injectJavaScript ( `
326+ ${ injectedVars }
327+ true;
328+ ` ) ;
329+
330+ // reinit using the canonical dataRef rather than the original prop
331+ createChart ( options , dataRef . current , bgColor ) ;
332+ }
333+ } ,
334+ [ options , data , bgColor ] ,
335+ ) ;
336+
245337 // Keep canonical copy of incoming prop `data` (convert typed arrays to plain arrays).
246338 // Also mirror to window._data for native platforms when webref is available.
247339 useEffect ( ( ) => {
@@ -603,19 +695,9 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
603695 if ( Platform . OS === 'web' ) {
604696 return (
605697 < View
606- ref = { ( r ) : any => {
607- containerRef . current = r ;
608- webref . current = r ;
609- if ( r ) {
610- createChart ( options , data ) ;
611- }
612- } }
698+ ref = { setWebRef }
613699 onLayout = { handleLayout }
614- style = { {
615- ...style ,
616- width : options ?. width || style ?. width || '100%' ,
617- height : options ?. height || style ?. height || '100%' ,
618- } }
700+ style = { memoizedContainerStyle }
619701 />
620702 ) ;
621703 } else {
@@ -624,79 +706,14 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
624706 { ...webviewProps }
625707 originWhitelist = { [ '*' ] }
626708 source = { html }
627- style = { {
628- ...style ,
629- width : options ?. width || style ?. width || '100%' ,
630- height : options ?. height || style ?. height || '100%' ,
631- } }
709+ style = { memoizedContainerStyle }
632710 scrollEnabled = { false }
633- onLoadEnd = { ( ) : void => {
634- // Use canonical dataRef when creating the native WebView chart
635- dataRef . current = toPlainArrays ( data as any [ ] ) as number [ ] [ ] ;
636- createChart ( options , dataRef . current , bgColor ) ;
637-
638- if ( onLoad ) {
639- onLoad ( ) ;
640- }
641- } }
642- ref = { ( r ) => {
643- if ( r ) {
644- var shouldReinit = containerRef . current && r !== webref . current ;
645-
646- if ( shouldReinit ) {
647- initialized . current = false ;
648- destroy ( true ) ;
649- }
650-
651- console . log ( 'shouldReinit' , shouldReinit ) ;
652- console . log ( 'data' , data ) ;
653-
654- containerRef . current = r ;
655- webref . current = r ;
656-
657- if ( shouldReinit ) {
658- // re-add any variables that were set
659- var injectedVars = '' ;
660- Object . keys ( variablesRef . current ) . forEach ( ( key ) => {
661- injectedVars += `window.${ key } = ${ JSON . stringify (
662- variablesRef . current [ key ] ,
663- ) } ;`;
664- } ) ;
665- webref . current . injectJavaScript ( `
666- ${ injectedVars }
667- true;
668- ` ) ;
669-
670- // reinit using the canonical dataRef rather than the original prop
671- createChart ( options , dataRef . current , bgColor ) ;
672- }
673- }
674- } }
711+ onLoadEnd = { handleLoadEnd }
712+ ref = { setWebRef }
675713 onLayout = { handleLayout }
676714 javaScriptEnabled = { true }
677715 injectedJavaScript = { `${ injectedJavaScript } ; true;` }
678- onMessage = { ( payload ) : void => {
679- // in webviewProps, if onMessage is provided, call it with the payload
680- if ( onMessage ) {
681- onMessage ( payload ) ;
682- return ;
683- }
684-
685- // Handle messages from the webview if needed
686- // console.log('Message from webview:', event.nativeEvent.data);
687- let dataPayload ;
688- try {
689- dataPayload = JSON . parse ( payload . nativeEvent . data ) ;
690- } catch ( e ) { }
691-
692- if ( dataPayload ) {
693- if ( dataPayload . type === 'Console' ) {
694- console . info ( `[Console] ${ JSON . stringify ( dataPayload . data ) } ` ) ;
695- } else {
696- console . log ( dataPayload ) ;
697- }
698- }
699- } }
716+ onMessage = { handleMessage }
700717 />
701718 ) ;
702719 }
0 commit comments