@@ -12,49 +12,75 @@ import { NoView } from './no_view';
12
12
import { View } from '../services/view_service/view' ;
13
13
import './app_container.scss' ;
14
14
15
- export const AppContainer = ( { view, params } : { view ?: View ; params : AppMountParameters } ) => {
16
- const isMobile = useIsWithinBreakpoints ( [ 'xs' , 's' , 'm' ] ) ;
17
- // TODO: Make this more robust.
18
- if ( ! view ) {
19
- return < NoView /> ;
15
+ export const AppContainer = React . memo (
16
+ ( { view, params } : { view ?: View ; params : AppMountParameters } ) => {
17
+ const isMobile = useIsWithinBreakpoints ( [ 'xs' , 's' , 'm' ] ) ;
18
+ // TODO: Make this more robust.
19
+ if ( ! view ) {
20
+ return < NoView /> ;
21
+ }
22
+
23
+ const { Canvas, Panel, Context } = view ;
24
+
25
+ const MemoizedPanel = memo ( Panel ) ;
26
+ const MemoizedCanvas = memo ( Canvas ) ;
27
+
28
+ // Render the application DOM.
29
+ return (
30
+ < EuiPage className = "deLayout" paddingSize = "none" >
31
+ { /* TODO: improve fallback state */ }
32
+ < Suspense fallback = { < div > Loading...</ div > } >
33
+ < Context { ...params } >
34
+ < EuiResizableContainer direction = { isMobile ? 'vertical' : 'horizontal' } >
35
+ { ( EuiResizablePanel , EuiResizableButton ) => (
36
+ < >
37
+ < EuiResizablePanel
38
+ initialSize = { 20 }
39
+ minSize = "260px"
40
+ mode = { [ 'collapsible' , { position : 'top' } ] }
41
+ paddingSize = "none"
42
+ >
43
+ < Sidebar >
44
+ < MemoizedPanel { ...params } />
45
+ </ Sidebar >
46
+ </ EuiResizablePanel >
47
+ < EuiResizableButton />
48
+
49
+ < EuiResizablePanel initialSize = { 80 } minSize = "65%" mode = "main" paddingSize = "none" >
50
+ < EuiPageBody className = "deLayout__canvas" >
51
+ < MemoizedCanvas { ...params } />
52
+ </ EuiPageBody >
53
+ </ EuiResizablePanel >
54
+ </ >
55
+ ) }
56
+ </ EuiResizableContainer >
57
+ </ Context >
58
+ </ Suspense >
59
+ </ EuiPage >
60
+ ) ;
61
+ } ,
62
+ ( prevProps , nextProps ) => {
63
+ return (
64
+ prevProps . view === nextProps . view &&
65
+ shallowEqual ( prevProps . params , nextProps . params , [ 'history' ] )
66
+ ) ;
67
+ }
68
+ ) ;
69
+
70
+ // A simple shallow equal function that can ignore specified keys
71
+ function shallowEqual ( object1 : any , object2 : any , ignoreKeys : any ) {
72
+ const keys1 = Object . keys ( object1 ) . filter ( ( key ) => ! ignoreKeys . includes ( key ) ) ;
73
+ const keys2 = Object . keys ( object2 ) . filter ( ( key ) => ! ignoreKeys . includes ( key ) ) ;
74
+
75
+ if ( keys1 . length !== keys2 . length ) {
76
+ return false ;
77
+ }
78
+
79
+ for ( const key of keys1 ) {
80
+ if ( object1 [ key ] !== object2 [ key ] ) {
81
+ return false ;
82
+ }
20
83
}
21
84
22
- const { Canvas, Panel, Context } = view ;
23
-
24
- const MemoizedPanel = memo ( Panel ) ;
25
- const MemoizedCanvas = memo ( Canvas ) ;
26
-
27
- // Render the application DOM.
28
- return (
29
- < EuiPage className = "deLayout" paddingSize = "none" >
30
- { /* TODO: improve fallback state */ }
31
- < Suspense fallback = { < div > Loading...</ div > } >
32
- < Context { ...params } >
33
- < EuiResizableContainer direction = { isMobile ? 'vertical' : 'horizontal' } >
34
- { ( EuiResizablePanel , EuiResizableButton ) => (
35
- < >
36
- < EuiResizablePanel
37
- initialSize = { 20 }
38
- minSize = "260px"
39
- mode = { [ 'collapsible' , { position : 'top' } ] }
40
- paddingSize = "none"
41
- >
42
- < Sidebar >
43
- < MemoizedPanel { ...params } />
44
- </ Sidebar >
45
- </ EuiResizablePanel >
46
- < EuiResizableButton />
47
-
48
- < EuiResizablePanel initialSize = { 80 } minSize = "65%" mode = "main" paddingSize = "none" >
49
- < EuiPageBody className = "deLayout__canvas" >
50
- < MemoizedCanvas { ...params } />
51
- </ EuiPageBody >
52
- </ EuiResizablePanel >
53
- </ >
54
- ) }
55
- </ EuiResizableContainer >
56
- </ Context >
57
- </ Suspense >
58
- </ EuiPage >
59
- ) ;
60
- } ;
85
+ return true ;
86
+ }
0 commit comments