acekyd / made-in-nigeria

Here is a curation of awesome tools built by Nigerians that can be used by anybody and from anywhere in the world.
https://madeinnigeria.dev
1.01k stars 401 forks source link

feat: persist projects to a store (demo) #272

Closed kaf-lamed-beyt closed 8 months ago

kaf-lamed-beyt commented 9 months ago

Figuring this out was quite tricky because of the limitation of RSCs when it comes to client-side state. But, the idea of passing data through props — as Segun suggested — rescued me.

So for now @acekyd, I have a demo. All the projects are in a store. At first, it was only present on the project's route, so I had to move it to the homepage since that'll be a landing zone for everyone who visits madeinnigeria.dev.

To test it, I tried accessing the store from the navbar component &mdash way up in the component tree — and logged the value to the console.

You can try testing it in the other routes too. When you see this, I'd love you to explain #268 again to me. I have a shallow understanding of what it seemed to explain.

codesandbox[bot] commented 9 months ago

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders
Open Preview

acekyd commented 8 months ago

Unsure if this approach would work. Doesn't look quite right yet especially with the manual passing of the props. I'd assume pages that could need the data will just call the store - because people could come in from a direct link e.g the creator's profile and not through the home page.

Let's flesh out #268 and see if that helps us come into a better solution.

kaf-lamed-beyt commented 8 months ago

That's true. Folks could visit an entirely different route other than the homepage.

In the meantime let me test and see if it does work on other pages.

acekyd commented 8 months ago

Sounds good @kaf-lamed-beyt

kaf-lamed-beyt commented 8 months ago

Hi @acekyd,

Circling back to drop some feedback. this thing is deep, lol!

I tried approaching it from the React.createContext() perspective since our goal is to make the projects available at the top level so other components can access the supposed project data.

But I ran into a blocker. We can't use React Context in server components and since all components/routes/pages are RSCs by default in the app router, it made it difficult.

I even went ahead to try it out. But I got the same "you're trying to use React.createContext() in a server comp...." error.

Although I found some experiments or explanations on createServerContext and caching a request in React, I couldn't figure out how it fits into what we're trying to accomplish.

Of all the stuff I read through on server context I think this one stood out to me. Perhaps you can try taking a look at it or anything related to server contexts and see if it'll be possible to use the info there.

For now... the traditional approach that works is to pass the project data through prop to all the pages that need it. So ideally, it becomes something similar to the snippet below if we want to also keep the data in the project store when we navigate to a page.

   const { addProjects: pushProjectsToStore, data: projectsData } =
    useProjectStore();

  useEffect(() => {
    if (projectsData.length > 0) return;

    pushProjectsToStore({ data: props.projects });
  }, [props.projects, projectsData.length, pushProjectsToStore]);
acekyd commented 8 months ago

Hi @kaf-lamed-beyt. I think we may have been going about this the wrong way or over-engineering lol. Read through the link you shared and these are the things that stood out.

So how do we move on from here: Let's reset all the crazy things we've done so far lol and do the following:

What do you think?

kaf-lamed-beyt commented 8 months ago

Ah yes. I like the sound of this @acekyd!

Okay, just so we are on the same page. It is more like a hooks approach, yeah? Instead, this time around, we're only exporting functions that manipulates the data from the single fetch request in that hook.

So, something like this?

import { filterProjects } from "/hooks/useProjects"

const filterByAuthorName = filterProject(...args)

And one last thing... I'm guessing you don't mean a literal React component, right? The whole idea is around a utility function that fetches data, keeps it in cache, and exports functions to manipulate such data with, no?

acekyd commented 8 months ago

lol yes I don’t mean a literal component lol. Just like you did for the mdx under utils for the articles. That should solve our problem.

--

Best, Adewale Abati Web Engineer & Developer Advocate, adewaleabati.com https://www.adewaleabati.com/ @ace_kyd https://twitter.com/ace_kyd

On Sun, Jan 28, 2024 at 6:23 PM null (for now) @.***> wrote:

Ah yes. I like the sound of this @acekyd https://github.com/acekyd!

Okay, just so we are on the same page. It is more like a hooks approach, yeah? Instead, this time around, we're only exporting functions that manipulates the data from the single fetch request in that hook.

So, something like this?

import { filterProjects } from "/hooks/useProjects" const filterByAuthorName = filterProject(...args)

And one last thing... I'm guessing you don't mean a literal React component, right? The whole idea is around a utility function that fetches data, keeps it in cache, and exports functions to manipulate such data with, no?

— Reply to this email directly, view it on GitHub https://github.com/acekyd/made-in-nigeria/pull/272#issuecomment-1913666968, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA6RNUU37DXR6YIWOGNKOLTYQ2CSRAVCNFSM6AAAAABCHBRBWWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMJTGY3DMOJWHA . You are receiving this because you were mentioned.Message ID: @.***>

kaf-lamed-beyt commented 8 months ago

Ah yes! Thanks for clarifying 😄

I'll do well to give you feedback during the week.

kaf-lamed-beyt commented 8 months ago

Wait @acekyd... I have no idea how this was merged. I pushed just now, only for me to realize it is merged.

acekyd commented 8 months ago

I was just as surprised... The revert PR button isn't coming up. Can you send a new PR with your new updates that also reverses this? @kaf-lamed-beyt

kaf-lamed-beyt commented 8 months ago

I think I know what happened...

I pushed to the upstream version of web-dev. I have two remotes setup for this project on my PC. origin points to my forked version at: "kaf-lamed-beyt/made-in-nigeria" while upstream points to "acekyd/made-in-nigeria". So when I did git push without specifying the origin, the changes were sent to this branch.

That aside, the changes I made are already here. See:

https://github.com/acekyd/made-in-nigeria/blob/77365d69ae75c899935f15c1399d9ddeeeddb8b6/app/utils/projects.ts#L58-L90

I also included some console.logs in /app/layout.tsx to see the functions in action.

https://github.com/acekyd/made-in-nigeria/blob/77365d69ae75c899935f15c1399d9ddeeeddb8b6/app/layout.tsx#L23-L31

The exported filterProjects function can also be used in the pages that need it.

Let me know if I should still open a new PR when you see this, @acekyd.

acekyd commented 8 months ago

This looks good! I wasn't sure if you'd finished the implementation yet - so no need for a new PR.

This current implementation only covers the setup right? Still have to update the other pages that currently use it? @kaf-lamed-beyt

kaf-lamed-beyt commented 8 months ago

Oh that sounds great! Thanks for letting me know @acekyd.

Yes, for now, it is just a base setup. I need to know the page that needs the data. For now, I think the /creators route, yes? So let's say we want to return projects created by an author when folks navigate to /creators/acekyd, for example, we should render all the projects for this author, right?

If yes, is there a UI for that?

acekyd commented 8 months ago

There's no UI for that yet @kaf-lamed-beyt but glad to see it's all set up. Thanks for all the work - much appreciated.

kaf-lamed-beyt commented 8 months ago

I'm glad I could help @acekyd!

Thanks for the opportunity!