You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(Android): avoid race condition related to state on the new arch (software-mansion#2024)
## Description
Fixes a race condition that is causing the layout of the screen to be
wrong when the window size is changed. The flow before this change was:
- window changes size (in this case keyboard is opened)
- layout is done, `onLayout` gets called in the `Screen` class
- frame is different than the one in the current state (window height is
reduced by the keyboard's height)
- native state is updated **asynchronously**
- window changes size again (in this case keyboard is closed)
- layout is done, `onLayout` gets called in the `Screen` class
- since the native state update hasn't been applied yet at this point,
the new frame is the same as the one stored in the native state, native
state update is skipped
- native state update is applied (the one with reduced height), shadow
node size gets changed
## Changes
- Fixed a race condition that resulted in the screen's children having
wrong dimensions when the window size was changed
<!--
## Screenshots / GIFs
Here you can add screenshots / GIFs documenting your change.
You can add before / after section if you're changing some behavior.
-->
### Before
https://github.com/software-mansion/react-native-screens/assets/21055725/eec27502-904e-461f-8762-21e24c9e0e8f
### After
https://github.com/software-mansion/react-native-screens/assets/21055725/aba69232-dd09-46b0-9063-09e090acdff4
(You may need to look at this one frame-by-frame. In some cases there is
one frame where the layout looks like in the `before` video, but it gets
corrected after.
## Test code and steps to reproduce
```jsx
import 'react-native-gesture-handler';
import {NavigationContainer} from '@react-navigation/native';
import React, {useRef} from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import {Button, TextInput, View} from 'react-native';
const Stack = createStackNavigator();
function Thing() {
const ref = useRef(null);
return (
<View style={{flex: 1, backgroundColor: 'wheat'}}>
<TextInput
ref={ref}
style={{backgroundColor: 'white', borderWidth: 1, borderColor: 'black'}}
/>
<Button
title="do the thing"
onPress={() => {
ref.current?.focus();
setTimeout(() => {
ref.current?.blur();
}, 30);
}}
/>
</View>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Thing} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
```
## Checklist
- [x] Included code example that can be used to test this change
- [x] Ensured that CI passes
0 commit comments