-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: Web rendering issues and welcome screen layout issue #2809
base: master
Are you sure you want to change the base?
Conversation
<ScrollView> | ||
<ScreenWithoutScrolling {...props} /> | ||
) : ( | ||
<ScreenWithScrolling {...props} /> | ||
)} | ||
</KeyboardAvoidingView> | ||
</ScrollView> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this is a root-cause fix. I'd like to make sure we look into what's going on and why so we know that this is where we want to fix it.
Note that in the original stack trace, the root of the error actually occurs in KeyboardAwareScrollView
.
Replacing KeyboardAwareScrollView also stops the issue from occurring:
function ScreenWithScrolling(props: ScreenProps) {
...
useScrollToTop(ref)
const MyComponent = Platform.OS === "web" ? ScrollView : KeyboardAwareScrollView
return (
<MyComponent
bottomOffset={keyboardBottomOffset}
{...{ keyboardShouldPersistTaps, scrollEnabled, ref }}
Also note that on the original issue @frankcalise linked this ticket where someone noted that adding import "setimmediate"
also appears to fix the issue. I tried this out and it appears to work, as well (setimmediate
is apparently brought in by fbjs
which is a dependency of react-native-web
.
I'm not opposed to an immediate fix to unblock things, but I think we definitely need to dig deeper into this to find and fix root cause.
I looked at the error in the dev console and it gives a clearer stack trace of the issue: that internal.js
file is part of react-native-keyboard-controller
. its use of setImmediate makes this not compatible with web.
I think the more appropriate fix is to swap out KeyboardAwareScrollView
for a regular scrollview, since it wasn't designed for web.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition, I think we should probably use a const to define a new component wrapping KeyboardAwareScrollView ? ScrollView
like we did with the useEffect
below, and export it from a file like it's a component. that way other components that may want to use this can get a version compatible with web, instead of everyone having to write a platform ternary.
</KeyboardAvoidingView> | ||
</ScrollView> | ||
) : ( | ||
<KeyboardAvoidingView |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have KeyboardAvoidingView if we also have KeyboardAwareScrollView nested within it? If we need it for the non-scrolling version, I would think:
- We wouldn't want to wrap KeyboardAvoidingView around both cases, only non-scrolling
- We wouldn't want to mix RN's KeyboardAvoidingView with RNKC's KeyboardAwareScrollView. It looks like RNKC has its own KeyboardAvoidingView.
@@ -57,7 +57,7 @@ export const WelcomeScreen: FC<WelcomeScreenProps> = observer( | |||
tx="welcomeScreen:readyForLaunch" | |||
preset="heading" | |||
/> | |||
<Text tx="welcomeScreen:exciting" preset="subheading" /> | |||
<Text tx="welcomeScreen:exciting" preset="subheading" style={$subheading} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is due to changes, see my comment over there
* therefore we want to use ScrollView just for web | ||
*/} | ||
{Platform.OS === "web" ? ( | ||
<ScrollView> | ||
<ScreenWithoutScrolling {...props} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also meant to ask: why does web only get ScreeenWithoutScrolling
? Shouldn't it have both options?
I think that's why this appeared to fix things, it removes KeyboardAwareScrollView
from the document.
Co-authored-by: Lizzi Lindboe <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finally got around to playing with this, I will attempt to look for a solution related to the ContentWrapperView
@@ -57,7 +57,7 @@ export const WelcomeScreen: FC<WelcomeScreenProps> = observer( | |||
tx="welcomeScreen:readyForLaunch" | |||
preset="heading" | |||
/> | |||
<Text tx="welcomeScreen:exciting" preset="subheading" /> | |||
<Text tx="welcomeScreen:exciting" preset="subheading" style={$subheading} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is due to changes, see my comment over there
const ContentWrapperView = | ||
Platform.OS === "web" | ||
? ScrollView | ||
: (props: KeyboardAvoidingViewProps) => ( | ||
<KeyboardAvoidingView | ||
behavior={isIos ? "padding" : "height"} | ||
keyboardVerticalOffset={keyboardOffset} | ||
{...KeyboardAvoidingViewProps} | ||
style={[$styles.flex1, KeyboardAvoidingViewProps?.style]} | ||
{...props} | ||
/> | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this exactly, could you give me more detail around why we chose ScrollView for web here, when KeyboardAvoidingView is not a ScrollView under the hood? Changing it to View makes the showroom screen a disaster, so it seems correct - I'm just unsure as to why
In addition to that, just assigning ContentWrapperView
this empty ScrollViiew
, we totally omit the style
and contentContainerStyle
coming from props
. Which is why @lindboe's screenshot from the other comment looks off. In the native version, we assign $styles.flex1
(plus spreading props), but for web this container doesn't receive any styles.
This isn't a final solution, but it helps:
const contentWrapperProps =
Platform.OS === "web"
? { style: $styles.flex1, contentContainerStyle: props.contentContainerStyle }
: {}
// ...
<ContentWrapperView {...contentWrapperProps}>
Please verify the following:
yarn test
jest tests pass with new tests, if relevantyarn lint
eslint checks pass with new code, if relevantyarn format:check
prettier checks pass with new code, if relevantREADME.md
(or relevant documentation) has been updated with your changesDescribe your PR
Closes #2807
This PR solves 3 issues:
Screen
component,KeyboardAvoidingView
is crashing in web. It was replaced by a normalScrollView
.useHeader
hook and web,useLayoutEffect
was creating a rendering loop. It is replaced byuseEffect
.Screenshots (if applicable)