From 09bb57b8257e8fffc7dd7bd58f6a8da5b62ad761 Mon Sep 17 00:00:00 2001 From: Him Date: Wed, 16 Oct 2019 23:00:30 +0800 Subject: [PATCH] Update for getDerivedStateFromProps --- lib/ActionSheetCustom.js | 151 ++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 72 deletions(-) diff --git a/lib/ActionSheetCustom.js b/lib/ActionSheetCustom.js index 7a0fc35..8781778 100644 --- a/lib/ActionSheetCustom.js +++ b/lib/ActionSheetCustom.js @@ -14,33 +14,35 @@ class ActionSheet extends React.Component { styles: {} } + static getDerivedStateFromProps(props, state) { + let translateY = calculateHeight(props) + let scrollEnabled = translateY > MAX_HEIGHT + if (scrollEnabled) { + translateY = MAX_HEIGHT + } + + if (state.translateY !== translateY) { + return { scrollEnabled, translateY }; + } + return null; + } + constructor (props) { super(props) - this.scrollEnabled = false - this.translateY = this._calculateHeight(props) + let translateY = calculateHeight(props) + let scrollEnabled = translateY > MAX_HEIGHT + if (scrollEnabled) { + translateY = MAX_HEIGHT + } + this.state = { + scrollEnabled, + translateY, visible: false, - sheetAnim: new Animated.Value(this.translateY) + sheetAnim: new Animated.Value(translateY) } } - componentWillReceiveProps (nextProps) { - this.translateY = this._calculateHeight(nextProps) - } - - get styles () { - const { styles } = this.props - const obj = {} - Object.keys(styles2).forEach((key) => { - const arr = [styles2[key]] - if (styles[key]) { - arr.push(styles[key]) - } - obj[key] = arr - }) - return obj - } - show = () => { this.setState({visible: true}, () => { this._showSheet() @@ -74,70 +76,32 @@ class ActionSheet extends React.Component { _hideSheet (callback) { Animated.timing(this.state.sheetAnim, { - toValue: this.translateY, + toValue: this.state.translateY, duration: 200 }).start(callback) } - /** - * elements: titleBox, messageBox, buttonBox, cancelButtonBox - * box size: height, marginTop, marginBottom - */ - _calculateHeight (props) { - const styles = this.styles - - const getHeight = (name) => { - const style = styles[name][styles[name].length - 1] - let h = 0 - ;['height', 'marginTop', 'marginBottom'].forEach((attrName) => { - if (typeof style[attrName] !== 'undefined') { - h += style[attrName] - } - }) - return h - } - - let height = 0 - if (props.title) height += getHeight('titleBox') - if (props.message) height += getHeight('messageBox') - if (utils.isset(props.cancelButtonIndex)) { - height += getHeight('cancelButtonBox') - height += (props.options.length - 1) * getHeight('buttonBox') - } else { - height += props.options.length * getHeight('buttonBox') - } - - if (height > MAX_HEIGHT) { - this.scrollEnabled = true - height = MAX_HEIGHT - } else { - this.scrollEnabled = false - } - - return height - } - _renderTitle () { - const { title } = this.props - const styles = this.styles + const { title, styles } = this.props + const mergedStyles = getMergedStyles(styles) if (!title) return null return ( - + {React.isValidElement(title) ? title : ( - {title} + {title} )} ) } _renderMessage () { - const { message } = this.props - const styles = this.styles + const { message, styles } = this.props + const mergedStyles = getMergedStyles(styles) if (!message) return null return ( - + {React.isValidElement(message) ? message : ( - {message} + {message} )} ) @@ -150,7 +114,7 @@ class ActionSheet extends React.Component { } _createButton (title, index) { - const styles = this.styles + const styles = getMergedStyles(this.props.styles) const { buttonUnderlayColor, cancelButtonIndex, destructiveButtonIndex, tintColor } = this.props const fontColor = destructiveButtonIndex === index ? WARN_COLOR : tintColor const buttonBoxStyle = cancelButtonIndex === index ? styles.cancelButtonBox : styles.buttonBox @@ -177,8 +141,8 @@ class ActionSheet extends React.Component { } render () { - const styles = this.styles - const { visible, sheetAnim } = this.state + const styles = getMergedStyles(this.props.styles) + const { visible, sheetAnim, scrollEnabled, translateY } = this.state return ( {this._renderTitle()} {this._renderMessage()} - {this._renderOptions()} + {this._renderOptions()} {this._renderCancelButton()} @@ -207,4 +171,47 @@ class ActionSheet extends React.Component { } } +/** + * elements: titleBox, messageBox, buttonBox, cancelButtonBox + * box size: height, marginTop, marginBottom + */ +function calculateHeight(props) { + const styles = getMergedStyles(props.styles) + + const getHeight = (name) => { + const style = styles[name][styles[name].length - 1] + let h = 0 + ;['height', 'marginTop', 'marginBottom'].forEach((attrName) => { + if (typeof style[attrName] !== 'undefined') { + h += style[attrName] + } + }) + return h + } + + let height = 0 + if (props.title) height += getHeight('titleBox') + if (props.message) height += getHeight('messageBox') + if (utils.isset(props.cancelButtonIndex)) { + height += getHeight('cancelButtonBox') + height += (props.options.length - 1) * getHeight('buttonBox') + } else { + height += props.options.length * getHeight('buttonBox') + } + + return height +} + +function getMergedStyles(styles) { + const obj = {} + Object.keys(styles2).forEach((key) => { + const arr = [styles2[key]] + if (styles[key]) { + arr.push(styles[key]) + } + obj[key] = arr + }) + return obj +} + export default ActionSheet