Skip to content

Commit b08fff6

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
Fix race condition in KeyboardAvoidingView
Summary: Changelog: Fix possible race condition inside `KeyboardAvoidingView` Fabric has different order of events In Fabric, `keyboardWillChangeFrame` event is fired before `onLayout`, but in Paper it is the other way around. `KeyboardAvoidingView` depends on the order of events to function properly. Inside `_relativeKeyboardHeight` 0 is returned if `this._frame` is null. To fix this, `bottom` margin is recalculated whenever `keyboardWillChangeFrame` or `onLayout` is triggered. Reviewed By: shergin Differential Revision: D22764192 fbshipit-source-id: 591ac59af4395a4d43c4e78e4fbc0ff118b292f8
1 parent 7c7f09e commit b08fff6

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

Libraries/Components/Keyboard/KeyboardAvoidingView.js

+18-10
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
6767
};
6868

6969
_frame: ?ViewLayout = null;
70+
_keyboardEvent: ?KeyboardEvent = null;
7071
_subscriptions: Array<EventSubscription> = [];
7172
viewRef: {current: React.ElementRef<any> | null, ...};
7273
_initialFrameHeight: number = 0;
@@ -91,12 +92,27 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
9192
}
9293

9394
_onKeyboardChange = (event: ?KeyboardEvent) => {
94-
if (event == null) {
95+
this._keyboardEvent = event;
96+
this._updateBottomIfNecesarry();
97+
};
98+
99+
_onLayout = (event: ViewLayoutEvent) => {
100+
this._frame = event.nativeEvent.layout;
101+
if (!this._initialFrameHeight) {
102+
// save the initial frame height, before the keyboard is visible
103+
this._initialFrameHeight = this._frame.height;
104+
}
105+
106+
this._updateBottomIfNecesarry();
107+
};
108+
109+
_updateBottomIfNecesarry = () => {
110+
if (this._keyboardEvent == null) {
95111
this.setState({bottom: 0});
96112
return;
97113
}
98114

99-
const {duration, easing, endCoordinates} = event;
115+
const {duration, easing, endCoordinates} = this._keyboardEvent;
100116
const height = this._relativeKeyboardHeight(endCoordinates);
101117

102118
if (this.state.bottom === height) {
@@ -116,14 +132,6 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
116132
this.setState({bottom: height});
117133
};
118134

119-
_onLayout = (event: ViewLayoutEvent) => {
120-
this._frame = event.nativeEvent.layout;
121-
if (!this._initialFrameHeight) {
122-
// save the initial frame height, before the keyboard is visible
123-
this._initialFrameHeight = this._frame.height;
124-
}
125-
};
126-
127135
componentDidMount(): void {
128136
if (Platform.OS === 'ios') {
129137
this._subscriptions = [

0 commit comments

Comments
 (0)