rt2zz / redux-persist

persist and rehydrate a redux store
MIT License
12.91k stars 862 forks source link

getting 'suspended while responding to synchronous input' error with react18 while lazy loading #1386

Closed imtheaman closed 2 years ago

imtheaman commented 2 years ago

Issue

when i use redux-persist alongwith redux-toolkit, it throws error when using lazy and suspense. when i comment out redux-persist code, there's no error. everythin's working normal.

Error

It's a React 18's concurrent ui related error, says to use useTransition hook, but don't know where to use it, i think implementation should be done inside the packages. when i load up the website, i have SecuredRoute component using router-v6, which checks if jwt token is in the store or not and based on that it navigates to home page or signin page. i think redux-persist is trying to load data from localstorage to the store, this way we have two tasks running together at the same time, one is changing the data which might cause transition error

Uncaught Error: A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.
    React 10
    workLoop scheduler.development.js:266
    flushWork scheduler.development.js:239
    performWorkUntilDeadline scheduler.development.js:533
    js scheduler.development.js:571
    js scheduler.development.js:633
    __require2 chunk-JXMXRRTK.js:35
    js index.js:6
    __require2 chunk-JXMXRRTK.js:35
    React 2
    __require2 chunk-JXMXRRTK.js:35
    js React
    __require2 chunk-JXMXRRTK.js:35
    js React
    __require2 chunk-JXMXRRTK.js:35
    <anonymous> react-dom_client:1

SecuredRoute.tsx

import { Navigate, Outlet } from 'react-router-dom';
import useAppSelector from '../hooks/useAppSelector';

const SecuredRoute: React.FC = () => {
  const token = useAppSelector(({ session }) => session.token);
  return token ? <Outlet /> : <Navigate to='/signin' replace={true} />;
};

store.ts

import { configureStore } from "@reduxjs/toolkit";
import storage from 'redux-persist/lib/storage';
import {
  FLUSH,
  PAUSE,
  PERSIST,
  persistReducer,
  persistStore,
  PURGE,
  REGISTER,
  REHYDRATE,
} from 'redux-persist';
import rootReducer from "../slices";

const persistConfig = {
  key: 'connect',
  storage
}

const persistedReducer = persistReducer(persistConfig, rootReducer)
export const store = configureStore({
  reducer: persistedReducer,
  devTools: process.env.NODE_ENV !== 'production',
  middleware: (getDefaultMiddleware) => getDefaultMiddleware({
    serializableCheck: {
      ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
    }
  })
});

export const persistor = persistStore(store)
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
imtheaman commented 2 years ago

basically it's a react-router issue and requested as a feature, mentioned here https://github.com/remix-run/react-router/issues/8860

imtheaman commented 2 years ago

update: react-router doesn't seem to have the issue, as i mentioned above when i comment out <PersistGate> i don't get the error anymore, so it's a redux-persist issue.

imtheaman commented 2 years ago

@codebutler please guide me a bit, i wanna persist my store.

imtheaman commented 2 years ago

mistakenly closed

imtheaman commented 2 years ago

okay. i've created my own persistent store. if there's any soln. please add it here. -----

jerrywcy commented 8 months ago

I don't know why, but I simply added a layer of Suspense out of my PersistGate and it magically worked