I have a pretty minimal app at the moment implementing redux (following the official redux docs) and implementing some persistence of the data to local storage. I am facing a very stressful problem where i get
Uncaught SyntaxError: Invalid or unexpected token (at layout.js:93:29)
in my console. If i leave the error there, the app completely crashed and i get:
Unhandled Runtime Error
ChunkLoadError: Loading chunk app/layout failed. (timeout: http://localhost:3000/_next/static/chunks/app/layout.js))
The thing is that the errors are kind of random. It usually occurs (but not always) in a first page load after running npx next dev
If i reload the page, everything starts working normally until i restart the server. Then the error appears again. I having a hard time trying to debug, specially because it can happen that i run npx next dev
4 ou 5 times and get no error, then it starts appearing again for a random number of server restarts. In any case, always, i can get rid of the error reloading the page.
Current code:
layout.tsx
import type { Metadata } from "next";
import "./globals.css";
import StoreProvider from "./StoreProvider";
export const metadata: Metadata = {
title: "App",
description: "App Description",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<body>
<StoreProvider>{children}</StoreProvider>
</body>
</html>
);
}
StoreProvider.tsx
"use client";
import { useRef, useEffect } from "react";
import { Provider } from "react-redux";
import { makeStore, AppStore } from "../redux/store";
import { updateUser } from "@/redux/user/userSlice";
export default function StoreProvider({
children,
}: {
children: React.ReactNode;
}) {
const storeRef = useRef<AppStore>();
if (!storeRef.current) {
// Create the store instance the first time this renders
storeRef.current = makeStore();
}
useEffect(() => {
if (storeRef.current !== undefined) {
storeRef.current.dispatch(
updateUser(JSON.parse(localStorage.getItem("user")!))
);
}
}, []);
return <Provider store={storeRef.current}>{children}</Provider>;
}
userSlice.ts
import { createSlice } from "@reduxjs/toolkit"
interface userInterface {
value: {
id: string | number,
email: string,
username: string | null,
avatar?: string | null,
name?: string,
lastname: string,
isAdmin?: string | boolean
} | null
}
const initialState: userInterface = {
value: null
}
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
updateUser: (state, action) => {
state.value = action.payload
localStorage.setItem('user', JSON.stringify(state.value))
},
clearUser: (state) => {
state.value = null
localStorage.removeItem('user')
}
}
})
export const userReducer = userSlice.reducer
export const { updateUser, clearUser } = userSlice.actions
store.ts
import { configureStore } from '@reduxjs/toolkit'
import {userReducer} from "./user/userSlice"
export const makeStore = () => {
return configureStore({
reducer: {user: userReducer}
})
}
export type AppStore = ReturnType<typeof makeStore>
export type RootState = ReturnType<AppStore['getState']>
export type AppDispatch = AppStore['dispatch']