Reputation: 11
Started development server on Expo, opened on browser on localhost:8081, expected the app to render but got an error:
This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition.
Call Stack
updateDehydratedSuspenseComponent
node_modules/react-dom/cjs/react-dom.development.js
updateSuspenseComponent
node_modules/react-dom/cjs/react-dom.development.js
beginWork
node_modules/react-dom/cjs/react-dom.development.js
beginWork$1
node_modules/react-dom/cjs/react-dom.development.js
performUnitOfWork
node_modules/react-dom/cjs/react-dom.development.js
workLoopSync
node_modules/react-dom/cjs/react-dom.development.js
renderRootSync
node_modules/react-dom/cjs/react-dom.development.js
performSyncWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js
flushSyncCallbacks
node_modules/react-dom/cjs/react-dom.development.js
commitRootImpl
http://localhost:8081/node_modules%5Cexpo-router%5Centry.bundle
commitRoot
node_modules/react-dom/cjs/react-dom.development.js
finishConcurrentRender
node_modules/react-dom/cjs/react-dom.development.js
performConcurrentWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js
workLoop
node_modules/scheduler/cjs/scheduler.development.js
flushWork
node_modules/scheduler/cjs/scheduler.development.js
performWorkUntilDeadline
node_modules/scheduler/cjs/scheduler.development.js
Collapse all 16 frames
On save the content is displayed correctly, but every time on reload i get that hydration error. No errors on Expo Go on Anroid phone.
Having trouble pinpointing the problem. Reload was working couple of days ago.
The expo-router structure:
app
| +html.tsx
| +not-found.tsx
| _layout.tsx
|
+---(app)
| | add-item.tsx
| | modal.tsx
| | _layout.tsx
| |
| \---(tabs)
| account.tsx
| items.tsx
| _layout.tsx
|
\---(auth)
login.tsx
_layout.tsx
_layout.tsx at the root of app-folder:
import React from 'react'
import { Provider } from 'react-redux'
import { store } from '@/src/redux/store'
import { ThemeProvider } from '@react-navigation/native'
import { useFonts } from 'expo-font'
import FontAwesome from '@expo/vector-icons/FontAwesome'
import { Slot } from 'expo-router'
import * as SplashScreen from 'expo-splash-screen'
import { useEffect } from 'react'
import { useColorScheme } from '@/src/components/useColorScheme'
import { useRouter } from 'expo-router'
import { DarkTheme, DefaultTheme } from '@react-navigation/native'
import { supabase } from '@/src/utils/supabase'
import { useAppDispatch } from '@/src/redux/hooks'
import { logout, setSession } from '@/src/redux/userSlice'
export const unstable_settings = {
initialRouteName: '(tabs)',
}
SplashScreen.preventAutoHideAsync()
export default function RootLayout() {
const [loaded, error] = useFonts({
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
...FontAwesome.font,
})
useEffect(() => {
if (error) throw error
}, [error])
useEffect(() => {
if (loaded) {
SplashScreen.hideAsync()
}
}, [loaded])
if (!loaded) {
return null
}
return (
<Provider store={store}>
<App />
</Provider>
)
}
function App() {
const colorScheme = useColorScheme()
const router = useRouter()
const dispatch = useAppDispatch()
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
if (session) {
dispatch(setSession(session))
router.replace('/(app)/(tabs)/items')
} else {
console.log('no user')
}
})
supabase.auth.onAuthStateChange((_event, session) => {
if (session) {
dispatch(setSession(session))
router.replace('/(app)/(tabs)/items')
} else {
console.log('no user')
dispatch(logout())
router.replace('/(auth)/login')
}
})
}, [])
return (
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Slot />
</ThemeProvider>
)
}
items.tsx, example of redux use:
import { useEffect } from 'react'
import { selectCatalog, setItems } from '@/src/redux/catalogSlice'
import { View, Pressable, StyleSheet, SafeAreaView } from 'react-native'
import SoldItemList from '@/src/components/SoldItemList'
import { Link } from 'expo-router'
import { Text } from '@/src/components/Themed'
import { Item } from '@/src/types/ItemInterface'
import { data } from '@/assets/data'
import { useAppDispatch, useAppSelector } from '@/src/redux/hooks'
export default function Items() {
const dispatch = useAppDispatch()
const user = useAppSelector((state) => state.user.session?.user)
const catalog: Item[] = useAppSelector(selectCatalog)
useEffect(() => {
if (catalog.length === 0) {
dispatch(setItems(data))
}
}, [catalog, dispatch])
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Text> User: {user?.email ? user.email : null}</Text>
<SoldItemList items={catalog} />
<View>
<Link href='/add-item' asChild>
<Pressable style={styles.button}>
<Text
lightColor='rgba(255,255,255,0.8)'
darkColor='rgba(255,255,255,0.8)'
>
Add item
</Text>
</Pressable>
</Link>
</View>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
content: {
flex: 1,
width: '100%',
maxWidth: 550,
alignItems: 'center',
justifyContent: 'center',
},
button: {
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 12,
paddingHorizontal: 32,
borderRadius: 4,
elevation: 3,
backgroundColor: '#910A67',
maxWidth: 200,
},
})
Deleted the project and went back couple of iterations, npm install & npm cache clean --force & npx expo start --clear, but the error persists. Switched browser and tried incognito mode.
package.json:
{
"name": "expo-app",
"main": "expo-router/entry",
"version": "1.0.0",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"test": "jest --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@expo/vector-icons": "^14.0.0",
"@react-native-async-storage/async-storage": "^1.21.0",
"@react-navigation/native": "^6.0.2",
"@reduxjs/toolkit": "^2.2.2",
"@supabase/supabase-js": "^2.40.0",
"@testing-library/react-native": "^12.4.4",
"expo": "~50.0.14",
"expo-font": "~11.10.3",
"expo-linking": "~6.2.2",
"expo-router": "~3.4.8",
"expo-splash-screen": "~0.26.4",
"expo-status-bar": "~1.11.1",
"expo-system-ui": "~2.9.3",
"expo-web-browser": "~12.8.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.73.6",
"react-native-elements": "^3.4.3",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
"react-native-url-polyfill": "^2.0.0",
"react-native-uuid": "^2.0.2",
"react-native-web": "~0.19.6",
"react-redux": "^9.1.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@types/jest": "^29.5.12",
"@types/react": "~18.2.45",
"jest": "^29.2.1",
"jest-expo": "~50.0.4",
"react-native-dotenv": "^3.4.11",
"react-test-renderer": "18.2.0",
"typescript": "^5.1.3"
},
"private": true
}
Upvotes: 0
Views: 489
Reputation: 11
Whew, what a treat this was. The error was caused by using .env with third party plugin react-native-dotenv, instead of utilizing the Expo with EXPO_PUBLIC prefix: https://docs.expo.dev/guides/environment-variables/
Upvotes: 0