DEV Community

Cover image for How to get logged User in Next.js app directly in Redux store? Example using iron-session
Mariusz
Mariusz

Posted on

How to get logged User in Next.js app directly in Redux store? Example using iron-session

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;
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

and the log-in usage:


  const { login, isLoading, error, isError, isSuccess, isUninitialized } = useLogIn();
Enter fullscreen mode Exit fullscreen mode

retrieving the data:

  const user = useSelector(selectUser);
Enter fullscreen mode Exit fullscreen mode

... and that is all folks!

PS. I might over-engineered it, let me know if there is simpler way.

Top comments (1)

Collapse
 
rofrol profile image
Roman Frołow

very nice. I searched how to use iron-session and couldn't find such example.