UNPKG

3.95 kBJavaScriptView Raw
1function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
3import * as React from 'react';
4import { View, StyleSheet } from 'react-native';
5export default class SceneView extends React.Component {
6 constructor(...args) {
7 super(...args);
8
9 _defineProperty(this, "state", {
10 loading: Math.abs(this.props.navigationState.index - this.props.index) > this.props.lazyPreloadDistance
11 });
12
13 _defineProperty(this, "timerHandler", void 0);
14
15 _defineProperty(this, "unsubscribe", null);
16
17 _defineProperty(this, "handleEnter", value => {
18 const {
19 index
20 } = this.props; // If we're entering the current route, we need to load it
21
22 if (value === index) {
23 this.setState(prevState => {
24 if (prevState.loading) {
25 return {
26 loading: false
27 };
28 }
29
30 return null;
31 });
32 }
33 });
34 }
35
36 static getDerivedStateFromProps(props, state) {
37 if (state.loading && Math.abs(props.navigationState.index - props.index) <= props.lazyPreloadDistance) {
38 // Always render the route when it becomes focused
39 return {
40 loading: false
41 };
42 }
43
44 return null;
45 }
46
47 componentDidMount() {
48 if (this.props.lazy) {
49 // If lazy mode is enabled, listen to when we enter screens
50 this.unsubscribe = this.props.addEnterListener(this.handleEnter);
51 } else if (this.state.loading) {
52 // If lazy mode is not enabled, render the scene with a delay if not loaded already
53 // This improves the initial startup time as the scene is no longer blocking
54 this.timerHandler = setTimeout(() => this.setState({
55 loading: false
56 }), 0);
57 }
58 }
59
60 componentDidUpdate(prevProps, prevState) {
61 if (this.props.lazy !== prevProps.lazy || this.state.loading !== prevState.loading) {
62 // We only need the listener if the tab hasn't loaded yet and lazy is enabled
63 if (this.props.lazy && this.state.loading) {
64 var _this$unsubscribe;
65
66 (_this$unsubscribe = this.unsubscribe) === null || _this$unsubscribe === void 0 ? void 0 : _this$unsubscribe.call(this);
67 this.unsubscribe = this.props.addEnterListener(this.handleEnter);
68 } else {
69 var _this$unsubscribe2;
70
71 (_this$unsubscribe2 = this.unsubscribe) === null || _this$unsubscribe2 === void 0 ? void 0 : _this$unsubscribe2.call(this);
72 }
73 }
74 }
75
76 componentWillUnmount() {
77 var _this$unsubscribe3;
78
79 (_this$unsubscribe3 = this.unsubscribe) === null || _this$unsubscribe3 === void 0 ? void 0 : _this$unsubscribe3.call(this);
80
81 if (this.timerHandler) {
82 clearTimeout(this.timerHandler);
83 this.timerHandler = undefined;
84 }
85 }
86
87 render() {
88 const {
89 navigationState,
90 index,
91 layout,
92 style
93 } = this.props;
94 const {
95 loading
96 } = this.state;
97 const focused = navigationState.index === index;
98 return /*#__PURE__*/React.createElement(View, {
99 accessibilityElementsHidden: !focused,
100 importantForAccessibility: focused ? 'auto' : 'no-hide-descendants',
101 style: [styles.route, // If we don't have the layout yet, make the focused screen fill the container
102 // This avoids delay before we are able to render pages side by side
103 layout.width ? {
104 width: layout.width
105 } : focused ? StyleSheet.absoluteFill : null, style]
106 }, // Only render the route only if it's either focused or layout is available
107 // When layout is not available, we must not render unfocused routes
108 // so that the focused route can fill the screen
109 focused || layout.width ? this.props.children({
110 loading
111 }) : null);
112 }
113
114}
115const styles = StyleSheet.create({
116 route: {
117 flex: 1,
118 overflow: 'hidden'
119 }
120});
121//# sourceMappingURL=SceneView.js.map
\No newline at end of file