Skip to content

Commit

Permalink
Prevent screen jump
Browse files Browse the repository at this point in the history
Android and iOS were both jumping when navigating from the Welcome
screen to the Demo Showroom screen (although in different directions,
and Android was less severe).

I found this issue was prevented when we use the `<StatusBar>` component
on the WelcomeScreen as well as DemoShowroom, so converted WelcomeScreen
to use the built-in `Screen` component, which includes `<StatusBar>`.

However, that raised another issue: when navigating from the Login
screen to the Welcome screen, the "fixed" `Screen` component on Welcome
screen would render the wrong height; it would be slightly too tall.
This didn't occur when changing presets and reloading the app via fast
refresh, which indicated to me that it was likely due to a state change
that was using the "old" screen dimensions from Login screen, but then
was incorrect after another state change took place on the Welcome
screen.

I found that was correct: the `useHeader` hook was using useEffect,
which means that header height wouldn't be set until the second render,
so when the KeyboardAvoidingView on on Welcome screen tried to render,
it had the wrong height information and rendered the wrong size.

By using `useLayoutEffect`, we make sure the header height is set before
any of the screen components try to render, fixing the issue.
  • Loading branch information
lindboe committed Aug 14, 2024
1 parent a1ae047 commit 97375b2
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 8 deletions.
10 changes: 3 additions & 7 deletions boilerplate/app/screens/WelcomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Image, ImageStyle, TextStyle, View, ViewStyle } from "react-native"
import {
Button, // @demo remove-current-line
Text,
Screen,
} from "app/components"
import { isRTL } from "../i18n"
import { useStores } from "../models" // @demo remove-current-line
Expand Down Expand Up @@ -46,7 +47,7 @@ export const WelcomeScreen: FC<WelcomeScreenProps> = observer(function WelcomeSc
const $bottomContainerInsets = useSafeAreaInsetsStyle(["bottom"])

return (
<View style={themed($container)}>
<Screen preset="fixed">
<View style={themed($topContainer)}>
<Image style={themed($welcomeLogo)} source={welcomeLogo} resizeMode="contain" />
<Text
Expand Down Expand Up @@ -75,16 +76,11 @@ export const WelcomeScreen: FC<WelcomeScreenProps> = observer(function WelcomeSc
/>
{/* @demo remove-block-end */}
</View>
</View>
</Screen>
)
// @mst replace-next-line }
})

const $container: ThemedStyle<ViewStyle> = ({ colors }) => ({
flex: 1,
backgroundColor: colors.background,
})

const $topContainer: ThemedStyle<ViewStyle> = ({ spacing }) => ({
flexShrink: 1,
flexGrow: 1,
Expand Down
4 changes: 3 additions & 1 deletion boilerplate/app/utils/useHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ export function useHeader(
) {
const navigation = useNavigation()

React.useEffect(() => {
// To avoid a visible header jump when navigating between screens, we use
// `useLayoutEffect`, which will apply the settings before the screen renders.
React.useLayoutEffect(() => {
navigation.setOptions({
headerShown: true,
header: () => <Header {...headerProps} />,
Expand Down

0 comments on commit 97375b2

Please sign in to comment.