react-native-gesture-handler
react-native-gesture-handler copied to clipboard
useLayoutEffect error on the terminal
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)
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
https://snack.expo.dev/@deouws/frowning-yellow-bananas
Please have a look at the below repository https://github.com/deouws/testGesture.git
Hey, please let me know if this PR fixes this issue for you
Hello , what should be the step to test the fixes on https://github.com/deouws/testGesture.git. ?
Thank you
@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 ../testGestureyarn 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.
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.
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
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
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.
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
- https://github.com/react-component/overflow/issues/6#issuecomment-819215239
- https://medium.com/@alexandereardon/uselayouteffect-and-ssr-192986cdcf7a
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?
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.