From 27dcb5b5d00bc42a5c64453e7a518dde8da2452d Mon Sep 17 00:00:00 2001 From: James Reggio Date: Fri, 1 Dec 2017 16:42:53 -0500 Subject: [PATCH] Await promise from Transitioner onTransitionStart (#2946) * Await promise from onTransitionStart * Review feedback * Update docs for onTransitionEnd --- .../docs/api/views/Transitioner.md | 8 ++++-- .../src/views/Transitioner.js | 26 ++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/react-navigation/docs/api/views/Transitioner.md b/packages/react-navigation/docs/api/views/Transitioner.md index e3f7cfc9..3e30a3fc 100644 --- a/packages/react-navigation/docs/api/views/Transitioner.md +++ b/packages/react-navigation/docs/api/views/Transitioner.md @@ -166,20 +166,24 @@ render: (transitionProps: NavigationTransitionProps, prevTransitionProps: ?Navig ### `onTransitionStart` function Invoked when the transition animation is about to start. +If you return a promise from `onTransitionStart`, the transition animation will begin after the promise is resolved. + #### Flow definition ```js -onTransitionStart: (transitionProps: NavigationTransitionProps, prevTransitionProps: ?NavigationTransitionProps) => void, +onTransitionStart: (transitionProps: NavigationTransitionProps, prevTransitionProps: ?NavigationTransitionProps) => (Promise | void), ``` #### Parameters - `transitionProps`: the current [NavigationTransitionProps](https://github.com/react-community/react-navigation/blob/master/src/TypeDefinition.js#L273) created from the current state and props - `prevTransitionProps`: the previous [NavigationTransitionProps](https://github.com/react-community/react-navigation/blob/master/src/TypeDefinition.js#L273) created from the previous state and props #### Returns -- none. +- `Promise` to delay the start of the transition animation, or none to begin the transition animation immediately. ### `onTransitionEnd` function Invoked once the transition animation completes. +If you return a promise from `onTransitionEnd`, any queued transition animations will begin after the promise is resolved. + #### Flow definition ```js onTransitionEnd: () => void diff --git a/packages/react-navigation/src/views/Transitioner.js b/packages/react-navigation/src/views/Transitioner.js index 2c09153e..eafc5286 100644 --- a/packages/react-navigation/src/views/Transitioner.js +++ b/packages/react-navigation/src/views/Transitioner.js @@ -172,12 +172,17 @@ class Transitioner extends React.Component { // update scenes and play the transition this._isTransitionRunning = true; - this.setState(nextState, () => { - nextProps.onTransitionStart && - nextProps.onTransitionStart( + this.setState(nextState, async () => { + if (nextProps.onTransitionStart) { + const result = nextProps.onTransitionStart( this._transitionProps, this._prevTransitionProps ); + + if (result instanceof Promise) { + await result; + } + } Animated.parallel(animations).start(this._onTransitionEnd); }); } @@ -231,9 +236,18 @@ class Transitioner extends React.Component { this._transitionProps = buildTransitionProps(this.props, nextState); - this.setState(nextState, () => { - this.props.onTransitionEnd && - this.props.onTransitionEnd(this._transitionProps, prevTransitionProps); + this.setState(nextState, async () => { + if (this.props.onTransitionEnd) { + const result = this.props.onTransitionEnd( + this._transitionProps, + prevTransitionProps + ); + + if (result instanceof Promise) { + await result; + } + } + if (this._queuedTransition) { this._startTransition( this._queuedTransition.nextProps,