#Check LocalStorage item before rendering the component

32 messages · Page 1 of 1 (latest)

ivory compass
#

Hey folks, I'm new to Qwik and want to implement some really simple logic: Check for the item in the LocalStorage, and if the item exists - render the component, if not - redirect to '/abc' page. The only way that I've found for now is to use useVisibleTask but it's executed after the component has been rendered, and it causes flushing . Is there a way to check the local storage before the actual render?

#

Maybe it's against the Qwik philosophy, so I would be grateful for any help or guidelines

versed flume
# ivory compass Hey folks, I'm new to Qwik and want to implement some really simple logic: Check...

Yes, so useVisibleTask$ is similar to something like a useEffect in React where it is executed eagerly on the client. We want to use it very sparingly. One major difference though, is that it is executed only in the viewport unless you explicitly change the strategy. (This is still a major benefit over something like a useEffect)

What you're looking for is useTask$, this is done pre-render
https://qwik.builder.io/docs/components/tasks/#usetask

My guess is you want something like this

  import { isBrowser } from '@builder.io/qwik/build';
  import { useTask$ } from '@builder.io/qwik';

  useTask$(() => {
    if (isBrowser) {
      const item = localStorage.getItem('yourItem');
      if (!item) {
        // do useNavigate instead for SPA navigation
        window.location.href = '/abc';
      }
    }
  });
Qwik

No hydration, auto lazy-loading, edge-optimized, and fun 🎉!

#

But because this is done at pre-render, I believe you need an isBrowser conditional since to get something from localstorage I think it needs to be on the client.

#

A visible task might make sense here if useTask doesn't do the trick

versed flume
#

Even then though, it is still a world of a difference better than the alternatives in other frameworks

ivory compass
#

Reply to: My guess is you want something like this

As far as I understand, the code above will never run in the browser(at least I've tried and nothing happened) the useTask runs only on the server side. Is there a way to say "Hey Qwik, please execute the following code ON BROWSER and BEFORE RENDER"

versed flume
#

Could be that I'm wrong though

#

the useTask runs only on the server side.

An important distinction: the useTask$ is on the server until there is a tracked change, then it is on the client.

#

and that is when it is mpa page load

#

it is on the client already on spa page load

#

TLDR it looks like a visible task makes the most sense here

ivory compass
#

In React and Vue I can create some sort of HOC and check the localstorage in this HOC and basically make the redirect call in this Wrapper component, before actually rendering the Children

ivory compass
#

High ordered component, basically wrapper for any Component. ProtectedRouter as an example

versed flume
#

If you can do it in React I doubt you couldn't do it in Qwik, but I don't understand because as soon as an effect is needed it's after rendering.

ivory compass
ivory compass
versed flume
#

This is why things don't re-render if they don't have to.

#

They can even be rendered out of order

ivory compass
#

Yep, I think that is the answer that I was looking for. Indeed, I forgot about this feature and it was flushing because of the content projection and the inline components are actually the solution here(at least it seems like the solution) So thanks again, I will try this approach

versed flume
#

@full palm is an inline component guru. He might be able to help if you're still stuck

#

😂

ivory compass
#

I was writing in Qwik using approaches from other framework, I need to focus more on Qwik philosophy and forget about all the React / Vue stuff

#

Have a nice day / night!

ivory compass
#

I found some workaround for this kind of problem, and it seems like it can be reused by any component. Basically I have created a ProtectedComponent that checks the value from localstorage and redirect to the another page if there is no such value. It might be a bad practice, but it's the only way(at least I didn't find another yet) to navigate from ComponentA to PageB without actually rendering the ComponentA. It works without "flushing"

 
export default component$(() => {
  const awaitedForLocalStorageCheck = useSignal(false);
  const naviage = useNavigate();

  useVisibleTask$(() => {
    const userId = getUserId();

    if (!userId) {
      naviage('/login');
    } else {
      awaitedForLocalStorageCheck.value = true;
    }
  });

  if (awaitedForLocalStorageCheck.value) {
    return <Slot />;
  }

  return null;
});
full palm
#

IMHO, when you're in an SPA app, and you're logged out, it should show a login modal on top of the page instead of redirecting. Then once login succeeds you refresh your data from the server and the modal disappears. That way you don't lose page state