Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any particular reason for an intermediary component to pass data to the client? #1

Open
unleashit opened this issue Mar 16, 2023 · 7 comments

Comments

@unleashit
Copy link

Great videos Blue Collar Coder! But since Providers is itself a RCC why not just send the data directly to it and initialize the client store from there? I haven't used Redux lately, but I've had the basic idea working with plain React Context and useReducer. Basic example:

export default async function Home() {
  const req = await fetch("http://localhost:3000/api/search");
  const data = await req.json();
  store.dispatch(setStartupPokemon(data));

  return (
    <main>
      <Providers data={data}>
        <SearchInput />
      </Providers>
    </main>
  );
}

Then something like this (where initStore returns the store with the now hydrated data as initial state):

function Providers({ data, children }: { data: Pokemon[], children: React.ReactNode }) {
  return (
    <Provider store={initStore(data)}>
        {children}
    </Provider>
  );
}
@jherr
Copy link
Owner

jherr commented Mar 16, 2023

That would definitely work as well. Thanks for that!

@unleashit
Copy link
Author

You bet. I'm as confused as anyone about the RSCs so confidence level around best practices isn't exactly high yet! I've learned a few tricks from you and appreciate it.

p.s. if you have a sec check out https://github.com/unleashit/fetch-cache and see if you think the idea is useful. Main thing it does over the default fetch is that it also works on the client (albeit not as fancy as React Query) and lets you log what's going on.

@jherr
Copy link
Owner

jherr commented Mar 16, 2023

They keep us content folks busy with new stuff, that's for sure.

Looked at fetch-cache. What would be good is an examples directory that showed how to use this across both server and client.

@unleashit
Copy link
Author

unleashit commented Mar 16, 2023

Don't want to go off topic too much, but thanks for taking a look and good suggestion. I'm not sure if it's worth investing much more time, but depending how it evolves on my projects (and I'm still using it), I certainly will do that. There's really not much currently different between client and server though, other than how you probably want to initialize it on the server (in React.cache if using Next 13 to avoid leaking between requests). Also caching on the server is always on per request lifecycle.

It's not trying to be a state manager. Basically I like the idea colocating data fetching in components but wanted more control than Next's patched fetch. This can access or see what's in cache, invalidate by key... plus comes part of the way towards being a combination of axios (double promise handling) and React Query (but without all the features lol).

@GLD5000
Copy link

GLD5000 commented Jul 23, 2023

@jherr great tutorial as always!

@unleashit Nice Idea! Something like this?

"use client";

import { Provider } from "react-redux";
import { store } from "@/store";
import { InitialData } from "@/types";
import { useRef } from "react";
import { setInitialData } from "@/store/searchSlice";

function Providers({
  initialData,
  children,
}: {
  initialData: InitialData[];
  children: React.ReactNode;
}) {
  const loaded = useRef(false);
  if (!loaded.current) {
    store.dispatch(setInitialData(initialData));
    loaded.current = true;
  }

  return <Provider store={store}>{children}</Provider>;
}

export default Providers;

@unleashit
Copy link
Author

Looks good to me I think, although I haven't been working with the app directory lately and am a bit out of the loop. I can't remember if Jack's solution covers it, but one piece of the puzzle was how to create/persist the store for use in server components, and only during the lifetime of the request. I ended up setting up a module that conditionally exported a React.cache() wrapped store or a normal version depending on typeof window. Then you can have access the store in server components, where context isn't allowed.

@GLD5000
Copy link

GLD5000 commented Jul 28, 2023

Great- thank you for taking a look! I also can't remember anything about persistence or state lifetimes in there- I shall have to delve deeper into the topic at some point!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants