[RN] Refactor AspectRatioDetector

Factor out the dimensions detection login into a DimensionsDetector component.
This commit is contained in:
Saúl Ibarra Corretgé 2018-02-02 13:21:14 +01:00 committed by Lyubo Marinov
parent 78fbfba573
commit 0ad1c88cd2
5 changed files with 105 additions and 32 deletions

View File

@ -1,33 +1,33 @@
import PropTypes from 'prop-types'; // @flow
import React, { Component } from 'react'; import React, { Component } from 'react';
import { View } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { DimensionsDetector } from '../../dimensions-detector';
import { setAspectRatio } from '../actions'; import { setAspectRatio } from '../actions';
import styles from './styles';
/**
* AspectRatioDetector component's property types.
*/
type Props = {
/**
* The "onDimensionsHandler" handler.
*/
_onDimensionsChanged: Function,
/**
* Any nested components.
*/
children: React$Node
};
/** /**
* A root {@link View} which captures the 'onLayout' event and figures out * A root {@link View} which captures the 'onLayout' event and figures out
* the aspect ratio of the app. * the aspect ratio of the app.
*/ */
class AspectRatioDetector extends Component { class AspectRatioDetector extends Component<Props> {
/**
* AspectRatioDetector component's property types.
*
* @static
*/
static propTypes = {
/**
* The "onLayout" handler.
*/
_onLayout: PropTypes.func,
/**
* Any nested components.
*/
children: PropTypes.node
};
/** /**
* Renders the root view and it's children. * Renders the root view and it's children.
* *
@ -35,11 +35,10 @@ class AspectRatioDetector extends Component {
*/ */
render() { render() {
return ( return (
<View <DimensionsDetector
onLayout = { this.props._onLayout } onDimensionsChanged = { this.props._onDimensionsChanged } >
style = { styles.aspectRatioDetector } >
{ this.props.children } { this.props.children }
</View> </DimensionsDetector>
); );
} }
} }
@ -50,21 +49,21 @@ class AspectRatioDetector extends Component {
* @param {Function} dispatch - Redux action dispatcher. * @param {Function} dispatch - Redux action dispatcher.
* @private * @private
* @returns {{ * @returns {{
* _onLayout: Function * _onDimensionsChanged: Function
* }} * }}
*/ */
function _mapDispatchToProps(dispatch) { function _mapDispatchToProps(dispatch) {
return { return {
/** /**
* Handles the "on layout" View's event and dispatches aspect ratio * Handles the "on dimensions changed" event and dispatches aspect ratio
* changed action. * changed action.
* *
* @param {Object} event - The "on layout" event object/structure passed * @param {number} width - The new width for the component.
* by react-native. * @param {number} height - The new height for the component.
* @private * @private
* @returns {void} * @returns {void}
*/ */
_onLayout({ nativeEvent: { layout: { height, width } } }) { _onDimensionsChanged(width: number, height: number) {
dispatch(setAspectRatio(width, height)); dispatch(setAspectRatio(width, height));
} }
}; };

View File

@ -0,0 +1,72 @@
// @flow
import React, { Component } from 'react';
import { View } from 'react-native';
import styles from './styles';
/**
* AspectRatioDetector component's property types.
*/
type Props = {
/**
* The "onLayout" handler.
*/
onDimensionsChanged: Function,
/**
* Any nested components.
*/
children: React$Node
};
/**
* A {@link View} which captures the 'onLayout' event and calls a prop with the
* component size.
*/
export default class DimensionsDetector extends Component<Props> {
/**
* Initializes a new DimensionsDetector instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Object) {
super(props);
this._onLayout = this._onLayout.bind(this);
}
_onLayout: (Object) => void;
/**
* Handles the "on layout" View's event and calls the onDimensionsChanged
* prop.
*
* @param {Object} event - The "on layout" event object/structure passed
* by react-native.
* @private
* @returns {void}
*/
_onLayout({ nativeEvent: { layout: { height, width } } }) {
const { onDimensionsChanged } = this.props;
onDimensionsChanged && onDimensionsChanged(width, height);
}
/**
* Renders the root view and it's children.
*
* @returns {Component}
*/
render() {
return (
<View
onLayout = { this._onLayout }
style = { styles.dimensionsDetector } >
{ this.props.children }
</View>
);
}
}

View File

@ -0,0 +1 @@
export { default as DimensionsDetector } from './DimensionsDetector';

View File

@ -5,9 +5,9 @@ import { createStyleSheet } from '../../styles';
*/ */
export default createStyleSheet({ export default createStyleSheet({
/** /**
* The style of {@link AspectRatioDetector} used on react-native. * The style of {@link DimensionsDetector} used on react-native.
*/ */
aspectRatioDetector: { dimensionsDetector: {
alignSelf: 'stretch', alignSelf: 'stretch',
flex: 1 flex: 1
} }

View File

@ -0,0 +1 @@
export * from './components';