#What's the correct way to distribute data to components?

15 messages · Page 1 of 1 (latest)

snow pagoda
#

I am trying to understand the correct way to distribute data to components without using props. As far as I can see, there are two ways to achieve this.

The first one is by importing routeLoader:

import { useAuth } from "~/routes/layout";
import { component$ } from "@builder.io/qwik";

export default component$(() => { 
  const user = useAuth();
  return (<p>{user.value.name}</p>);
});

The second one is using useContext:

// inserted value to contextprovider in layout
import { useAuthContextId } from "~/routes/layout";
import { component$, useContext } from "@builder.io/qwik";

export default component$(() => { 
  const user = useContext(useAuthContextId);
  return (<p>{user.value.name}</p>);
});

Also, am I doing something wrong with the usage of useContext? Do we really need to import and pass the context ID? I thought just writing the context ID name would be enough, like this:

const x = createContextId('user.data');
const val = useContext('user.data');

I thought importing routeLoader might be the wrong way to do it, as it would be invoked unnecessarily, but it seems like it is being invoked once regardless of how many times I call it in components or in loops. Then I checked the useContext result, and it contains data from other routeLoader as well (?). So, is routeLoader essentially a wrapper around useContext?

This might be general information for those who know JSX or React already, but this is my first time, and I'm a little bit lost in thought.

umbral dagger
#

Provider?

#

Did you put the provider??

#

//root.tsx or routes/layout.tsx
export type ChapterType = {
  id: number;
  title: string;
  description: string;
  isCompleted: boolean;
  uri: string;
};

export const ChaptersContext = createContextId<Signal<ChapterType[]>>(
  "docs.chapters-context",
);

export default component$(() => {
  useContextProvider(ChaptersContext, chapters);
  return <Slot />
});

//child components

import type { Signal } from "@builder.io/qwik";
import {  component$, useContext } from "@builder.io/qwik";


export default component$(() => {
   const chapters: Signal<ChapterType[]> = useContext(ChaptersContext);
 return <>components</>
})
snow pagoda
# umbral dagger Did you put the provider??

Yes, i know the context provider but my real question is:

  • should i import routeLoader from layout to components
    or
  • should i insert the routeLoader's data to context id in layout, and access to that data with useContext

I want to know what's correct way is, is useContext just an unnecessery step and i should just import the routeLoader because even if i import routeLoader in looped components it invoked just once... still i wanna know the correct way when distributing server data

golden schooner
# snow pagoda Yes, i know the context provider but my real question is: - should i import ro...

You should use routeLoader when you need data from server (e.g. fetching user info from database, external data from apis, fetching blog content, etc.) . The data from routeloader is available for all the children for that route. And routeloader will be run no matter if you use it or not.
Whether to use context or not goes back to whether we should use context or redux or zustand in react, and the answer is still the same: if you need simple state management and dont want to prop drill, context would be the way, but if you want to be more systematic and have sth like dispatch and handle, use a 3rd party library

#

tho I dont think you can use redux or somethiing similar in qiwk tho 🤔

snow pagoda
lethal lotus
#

I've found that I have never needed something like redux or zustand since the addition of signals.

#

because of signals, context is very efficient

snow pagoda
#

We used composables and useState within nuxtjs, so those things all new to me

golden schooner
# lethal lotus I've found that I have never needed something like redux or zustand since the ad...

agree with that, but I think the one of the reason why people uses redux or other libraries is simply becuase of separate of concerns, use global state management for global states, and context for passing props. Qwik signals are very easy to work and I love it more than solid styled signals, but sometimes it will still trigger a full-rerender of components depending on how the value is read. Aside from rendering performance and design principles, state libraries can also do sth like url state management and caching fetch requests. Indeed you can all implement them with signals but is a bit tedious and I would love if there are libraries out there that do them.

#

But all in all, I am not that experience in web dev and its really just my own experiences after some projects 😄

lethal lotus
#

trigger a full-rerender of components depending on how the value is read

This is whenever there is a structural change. For example, a ternary in the jsx. You can actually get around this by using a control flow component just like solid. It is "memoized" from the component$ in the control flow component.

Qwik has a vdom unlike solid. Solid's tradeoff is you have a limited set of what you can do with the jsx, but you get direct efficient updates.

#

The vdom is quite efficient though, because the components do not need to know about their children or parents.