diff --git a/packages/drawer/src/views/DrawerView.js b/packages/drawer/src/views/DrawerView.js index 843638ee..ec86cd0d 100644 --- a/packages/drawer/src/views/DrawerView.js +++ b/packages/drawer/src/views/DrawerView.js @@ -1,16 +1,36 @@ import React from 'react'; -import { Dimensions } from 'react-native'; +import { Dimensions, StyleSheet } from 'react-native'; import { SceneView } from '@react-navigation/core'; +// eslint-disable-next-line import/no-unresolved +import { ScreenContainer } from 'react-native-screens'; + import DrawerActions from '../routers/DrawerActions'; import DrawerLayout from './DrawerLayout'; import DrawerSidebar from './DrawerSidebar'; import DrawerGestureContext from '../utils/DrawerGestureContext'; +import ResourceSavingScene from '../views/ResourceSavingScene'; /** * Component that renders the drawer. */ export default class DrawerView extends React.PureComponent { + static defaultProps = { + lazy: true, + }; + + static getDerivedStateFromProps(nextProps, prevState) { + const { index } = nextProps.navigation.state; + + return { + // Set the current tab to be loaded if it was not loaded before + loaded: prevState.loaded.includes(index) + ? prevState.loaded + : [...prevState.loaded, index], + }; + } + state = { + loaded: [this.props.navigation.state.index], drawerWidth: typeof this.props.navigationConfig.drawerWidth === 'function' ? this.props.navigationConfig.drawerWidth() @@ -121,11 +141,12 @@ export default class DrawerView extends React.PureComponent { }; render() { - const { state } = this.props.navigation; - const activeKey = state.routes[state.index].key; - const descriptor = this.props.descriptors[activeKey]; - - const { drawerLockMode } = descriptor.options; + const { lazy, navigation } = this.props; + const { loaded } = this.state; + const { state } = navigation; + const { routes } = state; + const activeKey = routes[state.index].key; + const { drawerLockMode } = this.props.descriptors[activeKey].options; return ( - + + {routes.map((route, index) => { + if (lazy && !loaded.includes(index)) { + // Don't render a screen if we've never navigated to it + return null; + } + + const isFocused = navigation.state.index === index; + const descriptor = this.props.descriptors[route.key]; + + return ( + + + + ); + })} + ); } } + +const styles = StyleSheet.create({ + pages: { + flex: 1, + }, +}); diff --git a/packages/drawer/src/views/ResourceSavingScene.js b/packages/drawer/src/views/ResourceSavingScene.js new file mode 100644 index 00000000..f5d70767 --- /dev/null +++ b/packages/drawer/src/views/ResourceSavingScene.js @@ -0,0 +1,57 @@ +/* @flow */ + +import * as React from 'react'; +import { Platform, StyleSheet, View } from 'react-native'; + +// eslint-disable-next-line import/no-unresolved +import { Screen, screensEnabled } from 'react-native-screens'; + +type Props = { + isVisible: boolean, + children: React.Node, + style?: any, +}; + +const FAR_FAR_AWAY = 3000; // this should be big enough to move the whole view out of its container + +export default class ResourceSavingScene extends React.Component { + render() { + if (screensEnabled && screensEnabled()) { + const { isVisible, ...rest } = this.props; + return ; + } + const { isVisible, children, style, ...rest } = this.props; + + return ( + + + {children} + + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + overflow: 'hidden', + }, + attached: { + flex: 1, + }, + detached: { + flex: 1, + top: FAR_FAR_AWAY, + }, +});