I am trying to find a simple way to pass stateless session data (iron-session/JWT) to redux
store. There is a lot of solutions out there, but all of them do extra request. Obviously, decryption of cookie takes place on server side thus we can use it to pass the user
data as initial state. Here is my attempt:
// _app.tsx
function MyApp({
Component,
pageProps
}: AppProps
) {
store.dispatch(update(pageProps.user));
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
);
}
MyApp.getInitialProps = async function (appContext: AppContext) {
const req = appContext.ctx.req
const res = appContext.ctx.res;
const session = await getIronSession(req, res, sessionOptions);
return {
pageProps: {
user: session.user
},
}
}
export default MyApp;
Of course, using getInitialProps
on _app.tsx
block Next to do any static site generation, but that is not the crucial part for me.
We need to handle also the logging process on client side.
To make request, I use great react-toolkit queries, however to fill the same "redux slice" as on server side we will need to use some extra code.
Following, is my React hook, which basically pass the user data from "RTQ store" to defined and fully controlled Redux slice.
import { update } from "../../store/features/userSlice";
export function useLogIn() {
const [
login, {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
data,
isLoading,
isSuccess,
isError
}
] = useLoginMutation();
const dispatch = useDispatch();
useEffect(() => {
if (data?.user) {
dispatch(update(data?.user));
}
}, [ data ]);
return {
login,
isLoading,
isSuccess,
isError,
} as const;
}
and the log-in usage:
const { login, isLoading, error, isError, isSuccess, isUninitialized } = useLogIn();
retrieving the data:
const user = useSelector(selectUser);
... and that is all folks!
PS. I might over-engineered it, let me know if there is simpler way.
Top comments (1)
very nice. I searched how to use iron-session and couldn't find such example.