[RN] Don't destroy containers when they are not visible

This essentially reverts
023359b9d2

In the filmstrip we keep a container full of thumbnail views. Destroying these
every time we want we want to hide it is costly, as new renderers have to be
recreated, and they lack context, so there is an increased chance for "black
thumbnails".
This commit is contained in:
Saúl Ibarra Corretgé 2017-07-19 10:25:35 +02:00 committed by Lyubo Marinov
parent 2525bb2805
commit 157eadc44a
3 changed files with 49 additions and 19 deletions

View File

@ -69,11 +69,6 @@ export default class AbstractContainer extends Component {
...filteredProps ...filteredProps
} = props || this.props; } = props || this.props;
// visible
if (typeof visible !== 'undefined' && !visible) {
return null;
}
return React.createElement(type, filteredProps, children); return React.createElement(type, filteredProps, children);
} }
} }

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { import {
Dimensions,
TouchableHighlight, TouchableHighlight,
TouchableWithoutFeedback, TouchableWithoutFeedback,
View View
@ -28,26 +29,54 @@ export default class Container extends AbstractContainer {
*/ */
render() { render() {
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
let { onClick, style, touchFeedback, ...props } = this.props; let { onClick, style, touchFeedback, visible, ...props } = this.props;
// visible
// The following property is responsible to hide/show this Container by
// moving it out of site of the screen boundaries. An attempt to use the
// opacity property was made in order to eventually implement a
// fadeIn/fadeOut animation, however a known React Native problem was
// discovered, which allows the view to still capture touch events even
// if hidden.
let visibilityStyle;
if (typeof visible !== 'undefined' && !visible) {
const windowDimensions = Dimensions.get('window');
visibilityStyle = {
bottom: -windowDimensions.height,
right: -windowDimensions.width
};
}
// onClick & touchFeedback
(typeof touchFeedback === 'undefined') && (touchFeedback = onClick);
const renderParent = touchFeedback || onClick;
if (!renderParent && visibilityStyle) {
style = {
...style,
...visibilityStyle
};
}
// eslint-disable-next-line object-property-newline // eslint-disable-next-line object-property-newline
let component = this._render(View, { ...props, style }); let component = this._render(View, { ...props, style });
if (component) { if (renderParent) {
// onClick & touchFeedback const parentType
(typeof touchFeedback === 'undefined') && (touchFeedback = onClick); = touchFeedback
if (touchFeedback || onClick) { ? TouchableHighlight
const parentType : TouchableWithoutFeedback;
= touchFeedback const parentProps = {};
? TouchableHighlight
: TouchableWithoutFeedback;
const parentProps = {};
onClick && (parentProps.onPress = onClick); onClick && (parentProps.onPress = onClick);
visibilityStyle && (parentProps.style = visibilityStyle);
component component
= React.createElement(parentType, parentProps, component); = React.createElement(parentType, parentProps, component);
}
} }
return component; return component;

View File

@ -20,6 +20,12 @@ export default class Container extends AbstractContainer {
* @returns {ReactElement} * @returns {ReactElement}
*/ */
render() { render() {
const { visible } = this.props;
if (typeof visible !== 'undefined' && !visible) {
return null;
}
return this._render('div'); return this._render('div');
} }
} }