Skip to content

useLayoutEffect error on the terminal #3375

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

Open
deouws opened this issue Feb 3, 2025 · 11 comments · May be fixed by #3389
Open

useLayoutEffect error on the terminal #3375

deouws opened this issue Feb 3, 2025 · 11 comments · May be fixed by #3389
Labels
Platform: Web Repro provided A reproduction with a snack or repo is provided

Comments

@deouws
Copy link

deouws commented Feb 3, 2025

Description

λ ERROR Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.%s
GestureDetector (node_modules/react-native-gesture-handler/lib/commonjs/handlers/gestures/GestureDetector/index.js:76:47)
DraggableBox (app/index.tsx:14:35)
hrefAttrs (node_modules/react-native-web/dist/exports/View/index.js:35:24)
hrefAttrs (node_modules/react-native-web/dist/exports/View/index.js:35:24)
onScroll (node_modules/react-native-web/dist/exports/ScrollView/ScrollViewBase.js:57:23)
ScrollView (node_modules/react-native-web/dist/exports/ScrollView/index.js:33:4)
Route (node_modules/expo-router/build/Route.js:52:17)
route (node_modules/expo-router/build/useScreens.js:128:4)
StaticContainer (node_modules/@react-navigation/core/lib/commonjs/StaticContainer.js:14:15)
EnsureSingleNavigator (node_modules/@react-navigation/core/lib/commonjs/EnsureSingleNavigator.js:19:2)
SceneView (node_modules/@react-navigation/core/lib/commonjs/SceneView.js:20:2)
hrefAttrs (node_modules/react-native-web/dist/exports/View/index.js:35:24)
AnimatedHeaderHeightProvider (node_modules/@react-navigation/native-stack/lib/commonjs/views/NativeStackView.js:117:2)
hrefAttrs (node_modules/react-native-web/dist/exports/View/index.js:35:24)
hrefAttrs (node_modules/react-native-web/dist/exports/View/index.js:35:24)
(node_modules/react-native-web/dist/vendor/react-native/Animated/createAnimatedComponent.js:25:44)
Background (node_modules/@react-navigation/elements/lib/commonjs/Background.js:14:2)
Screen (node_modules/@react-navigation/elements/lib/commonjs/Screen.js:19:69)
hrefAttrs (node_modules/react-native-web/dist/exports/View/index.js:35:24)
SafeAreaProviderCompat (node_modules/@react-navigation/elements/lib/commonjs/SafeAreaProviderCompat.js:36:2)
NativeStackView (node_modules/@react-navigation/native-stack/lib/commonjs/views/NativeStackView.js:17:2)
PreventRemoveProvider (node_modules/@react-navigation/core/lib/commonjs/PreventRemoveProvider.js:38:2)
NavigationContent (node_modules/@react-navigation/core/lib/commonjs/useComponent.js:12:2)
children (node_modules/@react-navigation/core/lib/commonjs/useComponent.js:28:4)
NativeStackNavigator (node_modules/@react-navigation/native-stack/lib/commonjs/navigators/createNativeStackNavigator.js:14:2)
userDefinedChildren (node_modules/expo-router/build/layouts/withLayoutContext.js:75:62)
Route (node_modules/expo-router/build/Route.js:52:17)
route (node_modules/expo-router/build/useScreens.js:128:4)
hrefAttrs (node_modules/react-native-web/dist/exports/View/index.js:35:24)
NativeSafeAreaProvider (node_modules/react-native-safe-area-context/lib/commonjs/NativeSafeAreaProvider.web.js:29:2)
SafeAreaProvider (node_modules/react-native-safe-area-context/lib/commonjs/SafeAreaContext.js:28:2)
Html (node_modules/expo-router/build/static/html.js:23:16)
wrapper (node_modules/expo-router/build/static/renderStaticContent.js:66:24)
wrapper (node_modules/expo-router/build/ExpoRoot.js:53:23)
ThemeProvider (node_modules/@react-navigation/core/lib/commonjs/theming/ThemeProvider.js:13:2)
EnsureSingleNavigator (node_modules/@react-navigation/core/lib/commonjs/EnsureSingleNavigator.js:19:2)
BaseNavigationContainer (node_modules/@react-navigation/core/lib/commonjs/BaseNavigationContainer.js:79:2)
NavigationContainerInner (node_modules/expo-router/build/fork/NavigationContainer.js:32:36)
ContextNavigator (node_modules/expo-router/build/ExpoRoot.js:73:28)
ExpoRoot (node_modules/expo-router/build/ExpoRoot.js:47:29)
AppContainer (../shim:react-native-web/dist/exports/AppRegistry/AppContainer.js:4:24)
ServerContainer (node_modules/@react-navigation/native/lib/commonjs/ServerContainer.js:21:2)
λ Bundled 628ms node_modules/expo-router/node/render.js (874 modules)
Web Bundled 1268ms node_modules/expo-router/entry.js (983 modules)
Web Bundled 265ms node_modules/expo-router/entry.js (933 modules)
LOG [web] Logs will appear in the browser console

Steps to reproduce

https://github.com/software-mansion/react-native-gesture-handler/blob/main/example/src/simple/draggable/index.tsx

The above code was used in react-native app

Snack or a link to a repository

https://github.com/deouws/testGesture.git

Gesture Handler version

2.21.2

React Native version

0.76.2

Platforms

Web

JavaScript runtime

None

Workflow

None

Architecture

None

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

@deouws
Copy link
Author

deouws commented Feb 3, 2025

@github-actions github-actions bot added Repro provided A reproduction with a snack or repo is provided and removed Missing repro labels Feb 3, 2025
@deouws
Copy link
Author

deouws commented Feb 3, 2025

Please have a look at the below repository
https://github.com/deouws/testGesture.git

@latekvo latekvo linked a pull request Feb 6, 2025 that will close this issue
@latekvo
Copy link
Contributor

latekvo commented Feb 6, 2025

Hey, please let me know if this PR fixes this issue for you

@deouws
Copy link
Author

deouws commented Feb 6, 2025

Hello , what should be the step to test the fixes on https://github.com/deouws/testGesture.git. ?

Thank you

@latekvo
Copy link
Contributor

latekvo commented Feb 10, 2025

@deouws let me know if the following steps work:

Open your terminal and navigate to your testGesture app:

  • cd path/to/testGesture

Then enter the parent directory:

  • cd ..

Clone the react-native-gesture-handler repo:

  • git clone https://github.com/software-mansion/react-native-gesture-handler/

Enter the Gesture Handler, the checkout to the branch with the fix:

  • git checkout @latekvo/fix-ssr-layout-effect-warning

By now here is how your file structure should look like:

- parent_directory/
   - react-native-gesture-handler/
   - testGesture/

Then navigate back to testGesture, and add the cloned repo as your react-native-gesture-handler package:

  • cd ../testGesture
  • yarn add ../react-native-gesture-handler

If the yarn add command fails (it shouldn't), go back to the Gesture Handler directory, run npm pack, then yarn add the file that will be generated by npm pack instead of adding the entire Gesture Handler directory.

@nmpereira
Copy link

Running into the same issue, i changed the code in my node_modules/react-native-gesture-handler/lib/commonjs/handlers/gestures/GestureDetector/index.js to have useSafeLayoutEffect as in the PR linked and it gets rid of that error.

@nmpereira
Copy link

nmpereira commented Mar 6, 2025

Im not able to test via the instructions above as i get an error, but thats likely because of how Im building it

Logs for your project will appear below. Press Ctrl+C to exit.
λ Bundling failed 1273ms node_modules/expo-router/node/render.js (1241 modules)
Web Bundling failed 1278ms node_modules/expo-router/entry.js (1456 modules)

Metro error: Unable to resolve module ../../react-native-gesture-handler from /<>/<>/<>/<myapp>/app/_layout.tsx: 

None of these files exist:
  * ../react-native-gesture-handler(.web.ts|.ts|.web.tsx|.tsx|.web.js|.js|.web.jsx|.jsx|.web.json|.json|.web.cjs|.cjs|.web.mjs|.mjs|.web.scss|.scss|.web.sass|.sass|.web.css|.css|.web.css|.css)
  * ../react-native-gesture-handler
  12 | import React from "react";
  13 | import Header from "@/components/Header";
> 14 | import { GestureHandlerRootView } from '../../react-native-gesture-handler';

From my manual change in my own node_modules, it works perfectly

@deouws
Copy link
Author

deouws commented Mar 6, 2025

Sorry for late update. Here is the error I am getting when followed the steps advised earlier

Server Error
While trying to resolve module react-native-gesture-handler from file /private/tmp/testGesture/app/index.tsx, the package /private/tmp/testGesture/node_modules/react-native-gesture-handler/package.json was successfully found. However, this package itself specifies a main module field that could not be resolved (/private/tmp/testGesture/node_modules/react-native-gesture-handler/lib/commonjs/index.js. Indeed, none of these files exist:

  • /private/tmp/testGesture/node_modules/react-native-gesture-handler/lib/commonjs/index.js(.web.ts|.ts|.web.tsx|.tsx|.web.js|.js|.web.jsx|.jsx|.web.json|.json|.web.cjs|.cjs|.web.mjs|.mjs|.web.scss|.scss|.web.sass|.sass|.web.css|.css)
  • /private/tmp/testGesture/node_modules/react-native-gesture-handler/lib/commonjs/index.js/index(.web.ts|.ts|.web.tsx|.tsx|.web.js|.js|.web.jsx|.jsx|.web.json|.json|.web.cjs|.cjs|.web.mjs|.mjs|.web.scss|.scss|.web.sass|.sass|.web.css|.css)
    Source

@latekvo
Copy link
Contributor

latekvo commented Mar 6, 2025

Hey, just a heads-up, the PR with the fix is likely flawed - we're using useLayoutEffect instead of useEffect in order to fix a react-freeze bug.
Replacing the useLayoutEffect with useEffect might reintroduce that react-freeze issue. I'll look into this further.


Regarding applying the fix, the following method is simpler:

If you're using npm:

  • npm install "https://github.com/software-mansion/react-native-gesture-handler.git#@latekvo/fix-ssr-layout-effect-warning" --save

If you're using yarn:

  • yarn add react-native-gesture-handler@software-mansion/react-native-gesture-handler#@latekvo/fix-ssr-layout-effect-warning

That's all the installation steps, the app should have the PR applied after running one of these commands.

@nmpereira
Copy link

nmpereira commented Mar 7, 2025

From what i understand, useLayoutEffect works on react-native mobile, but on react-native-web, it shows an error. Im not sure why but a couple of libraries I'm using for react-native are showing this error. Currently I'm seeing the same error with https://github.com/gorhom/react-native-bottom-sheet as well which hasnt patched it (I'll open the same issue on there as well!).

However, gluestack seems to have patched it https://github.com/gluestack/gluestack-ui/blob/main/packages/styled/react/src/hooks/useSafeLayoutEffect.ts#L3

Im seeing the same fix in multiple issue threads

Disclaimer: I'm sorta new to react-native (and react), so i dont fully understand how this works, but from my research above, it seems like condiionally patching the useLayoutEffect to use useEffect based on where it's running is the way to go. I'm just not sure about the side effects of patching it. For now, im fine with using the PR fix as a workaround!

Thoughts?

@latekvo
Copy link
Contributor

latekvo commented Mar 8, 2025

Hey, in majority of cases, the useLayoutEffect cannot be trivially replaced by useEffect as both of these hooks serve a different purpose. What useIsomorphicEffect or useSafeEffect patches are doing is exactly that simple replacement.
As I said, I'll look into the exact issue more, as it all depends on whether the react-freeze bug persists with SSR or not.
It's likely we'll have to work around using useLayoutEffect, as simply replacing it with useEffect might just hide reintroduction of the react-freeze bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Web Repro provided A reproduction with a snack or repo is provided
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants