Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
fuf
Sep 12, 2004

haha

hey mom its 420 posted:

I think that should work actually, you just have to put a 'use server' directive inside the handleChange function. client components can get passed server actions as props no problem.

Oh wow, uhh yeah that worked. That's pretty amazing, thank you.

For some reason I thought if I had "use server" at the top of the file then putting "use server" on functions within the component wouldn't make any difference.

Adbot
ADBOT LOVES YOU

hey mom its 420
May 12, 2007

yeah, that's understandable, it would kind of make sense that a function defined inside a server component would count as a server action. but if that were the case, then you couldn't define normal helper functions inside the same scope without making them server actions.

that's why I prefer having multiple files for a single server component, and having server actions be in a separate file with 'use server' on top. It's also better for security because then you avoid some of the pitfalls where you could potentially leak server secrets via closures in server actions.

Roadie
Jun 30, 2013
I stll think the whole approach with dictating behavior based on text strings and intermingling client/server code like that is bonkers and a total footgun, and I will be really surprised if the whole RSC structure still exists as-is in 5 or 10 years, let alone becoming popular enough to be the next phase of React in the way that function components and hooks were.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

Roadie posted:

I stll think the whole approach with dictating behavior based on text strings and intermingling client/server code like that is bonkers and a total footgun, and I will be really surprised if the whole RSC structure still exists as-is in 5 or 10 years, let alone becoming popular enough to be the next phase of React in the way that function components and hooks were.

yeah i kinda agree. my only exposure to that code is via this thread, but I'm struggling to understand what the issue was with getServerSideProps(). It seems very straightforward to me??

abraham linksys
Sep 6, 2010

:darksouls:

teen phone cutie posted:

yeah i kinda agree. my only exposure to that code is via this thread, but I'm struggling to understand what the issue was with getServerSideProps(). It seems very straightforward to me??

i think there's this idea that having to define the data your application needs based off a single route, instead of the actual components rendered on that route, is limiting. as time goes on, i'm not convinced it actually is

Roadie
Jun 30, 2013
To me the reasonable answer to "I want to split data loading further" isn't RSC, it's taking the already-existing idea of slots and having arbitrary sub-"pages" that each do simultaneous async data stuff.

hey mom its 420
May 12, 2007

I don't know, I think the whole concept is really good and has benefits not only for performance and user experience but also dx and colocation, code simplicity etc. Some of the implementation choices are a little weird, like the string directives, and having only file system based routing. Also their overly aggressive caching, etc. But overall there's some great stuff in there. Especially nested layouts, suspense and transitions + server actions.

hey mom its 420
May 12, 2007

teen phone cutie posted:

yeah i kinda agree. my only exposure to that code is via this thread, but I'm struggling to understand what the issue was with getServerSideProps(). It seems very straightforward to me??

it was bad in practice imo. just colocate your components with the data they need. with getServerSide props, each page has to know all of the data its child components might need and has to arrange for it to be there and you have to plumb it out to them.

having components fetch their own data and arranging when this happens with suspense boundaries owns. for instance, a component that displays your account balance or whatever. once you have that, you can just put it anywhere in your code and it will do its thing. the requests they make are deduped (in rsc as well as client-side libs like react-query). plus, they're really easy to test. you also don't have to mess around with endpoints, REST, de/serialization, etc. you just write something like `const balance = await userService.getBalance()` in the component and then slap the result into a pretty <div>

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

abraham linksys posted:

i think there's this idea that having to define the data your application needs based off a single route, instead of the actual components rendered on that route, is limiting. as time goes on, i'm not convinced it actually is

if working on multiple different front-end teams who abuse the absolute living poo poo out of redux and other state management has taught me anything, it's that defining your data requests in one route is much better.

prop drilling is a much better issue to work through rather than have co-workers who are creating horrific component trees.

like seriously so many people still to this day don't understand why components should be dumb

teen phone cutie fucked around with this message at 23:07 on Apr 6, 2024

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
at work we have select fields that request data, that will either render a select or a spinner. in a nextjs app. which is just.....

that much flexibility is just not good imo

teen phone cutie fucked around with this message at 23:13 on Apr 6, 2024

hey mom its 420
May 12, 2007

teen phone cutie posted:

at work we have select fields that request data, that will either render a select or a spinner. in a nextjs app. which is just.....
that's why you use suspense instead of letting it handle its own loading state. but colocating components to the data they need is the way to go imo.

fuf
Sep 12, 2004

haha
Here's another NextJS question that I'm hoping I might be overthinking and might have a simple answer:

Say I have a /category/[categoryId]/ route that lists all the posts in a category.

But I also want a search filter on this page which persists per category page.

So on page /category/1/ I can set the search text to "foo", on /category/2/ to "bar", and then navigating back to /category/1/ will switch the search text back to "foo".

I know you can store stuff in the URL using searchParams but I'm not sure how this would work for navigating between multiple categories each with their own search text - maybe they can all be stored in the URL at the same time but that seems like a lot.

I think I could use a global state manager like Zustand and create a store of "CategorySearchFilter" objects.

But is there an easier way? Basically a kind of per-page persistent state?

hey mom its 420
May 12, 2007

What would you expect to happen when you just F5 the page? My guess would be for them to remain there, right? If so, then I think your choices are either storing them in the URL (might make it kind of long, but probably your best bet), cookies or local storage. If you go for local storage or cookies, you have to assign each page some kind of key (you'll probably be using categoryId) and then create a mapping from keys to filters.

fuf
Sep 12, 2004

haha

hey mom its 420 posted:

What would you expect to happen when you just F5 the page? My guess would be for them to remain there, right? If so, then I think your choices are either storing them in the URL (might make it kind of long, but probably your best bet), cookies or local storage. If you go for local storage or cookies, you have to assign each page some kind of key (you'll probably be using categoryId) and then create a mapping from keys to filters.

Thanks. I actually don't really mind if F5 wipes everything, which is why something like zustand might be an option.

The thing I don't get about using the URL is how to persist the same searchParams object across all the different routes.

I did have something that was using the URL to filter by tag ID that looked like this:
JavaScript code:
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();

const handleToggle = async () => {
    const params = new URLSearchParams(searchParams);
    const tagId = tag.id;
    (searchParams.get("filter") === tagId) ? params.delete("filter") : params.set("filter", tagId);
    router.push(`${pathname}?${params.toString()}`);
}
And then I could get the filter in the /category/[categoryId] page like this:
JavaScript code:
export default async function Page({
  params,
  searchParams,
}: {
  params: { categoryId: string };
  searchParams: { [key: string]: string | undefined };
})
But what about all the other routes the user might hit in between toggling the tag filter and returning to the category page? /post/123/, /settings/, etc. etc.

At the moment I'm linking to routes all over the place using <Link>, like this:
JavaScript code:
<Link href={`/category/${category.id}/presets`}>
   <div>{category.name} presets</div>
</Link>
I think I would need to update everywhere I use <Link> to somehow append the searchParams object each time?

M31
Jun 12, 2012
The underlying history api has a state option, but it's not exposed by next.js. Personally, I would probably use session storage (or local storage) with usePathname as the key.

kedo
Nov 27, 2007

Totally off topic from this current conversation, but can anyone recommend tools to add issue size/weight to Github issues and/or projects? I'm hesitantly open to non-Github tools, but Github is so deeply ingrained in our existing process that I'd really rather not have to reinvent the wheel if I don't have to.

pentium166
Oct 15, 2012

kedo posted:

Totally off topic from this current conversation, but can anyone recommend tools to add issue size/weight to Github issues and/or projects? I'm hesitantly open to non-Github tools, but Github is so deeply ingrained in our existing process that I'd really rather not have to reinvent the wheel if I don't have to.

It looks like some of the GitHub Projects templates have a size field. Do you want to add that to an existing project or issues or something?

kedo
Nov 27, 2007

pentium166 posted:

It looks like some of the GitHub Projects templates have a size field. Do you want to add that to an existing project or issues or something?

You're totally right, and I just somehow missed that entirely. Thank you for pointing it out! :cheers:

prom candy
Dec 16, 2005

Only I may dance
My prediction is that the Remix implementation of RSC is going to be way better than what NextJS is doing. They've got the benefit of seeing all of Next's mistakes and also imo Remix has always been a much easier framework to reason about than Next, even pre-RSC.

hey mom its 420
May 12, 2007

Yeah, looking forward to what they do with RSC. Maybe it's my limited imagination, but I can't imagine that the API will be much different conceptually. You'll probably have nested layouts and then server components fetching their own stuff, just like in next. One thing that I'd really like would be configuration based routing (instead of file-based). I'm into monorepos and it would be cool if you could easily built a feature library for some feature and then in your main app just say: okay, mount this onto this route, and then it would handle its own routing from there forward.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

prom candy posted:

My prediction is that the Remix implementation of RSC is going to be way better than what NextJS is doing. They've got the benefit of seeing all of Next's mistakes and also imo Remix has always been a much easier framework to reason about than Next, even pre-RSC.

I have been very, very happy with Remix.

prom candy
Dec 16, 2005

Only I may dance

hey mom its 420 posted:

Yeah, looking forward to what they do with RSC. Maybe it's my limited imagination, but I can't imagine that the API will be much different conceptually. You'll probably have nested layouts and then server components fetching their own stuff, just like in next. One thing that I'd really like would be configuration based routing (instead of file-based). I'm into monorepos and it would be cool if you could easily built a feature library for some feature and then in your main app just say: okay, mount this onto this route, and then it would handle its own routing from there forward.

Remix has configuration based routing if you want to override the file-based routing. I used it to build an app where lots of different subviews can be triggered from different parent views (i.e. pop open the customer overlay from the invoices screen, or the invoice overlay from the customers screen)


Lumpy posted:

I have been very, very happy with Remix.

Same for the most part. Probably my biggest complaint is the ergonomics around useFetcher can be very annoying. I wish it had callbacks or any other better way of hooking into the lifecycle besides useEffect. Basically I want react-query's API for it.

In that sense I'm pretty interested to see what happens with TanStack's metaframework.

pentium166
Oct 15, 2012
I've been poking at React as a learning experience recently, rewriting a small Vue 3 app I built (itself a recreation of a small internal Rails app I made at my last job), and all I have learned is that I hate React and its routing/state management ecosystem and wish literally anything else had won the frontend wars

And then people decided to run this cursed abomination on the backend as well!

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

pentium166 posted:

I've been poking at React as a learning experience recently, rewriting a small Vue 3 app I built (itself a recreation of a small internal Rails app I made at my last job), and all I have learned is that I hate React and its routing/state management ecosystem and wish literally anything else had won the frontend wars

And then people decided to run this cursed abomination on the backend as well!
Do you have any substantive complaints? Which routing and state management solutions did you explore?

Yeah, it kind of sucks React doesn't prescribe a single way of doing global state management or routing and you're forced to make a choice from a multitude of satisfactory options. But "cursed"?

zokie
Feb 13, 2006

Out of many, Sweden
I mean come on, React is a presentation library. It’s not your state management thing or your routing. So if you think it sucks, then React is not your problem

fsif
Jul 18, 2003

zokie posted:

I mean come on, React is a presentation library. It’s not your state management thing or your routing. So if you think it sucks, then React is not your problem

There aren't a ton of web projects you can architect without state management or routing.

pentium166
Oct 15, 2012

Ima Computer posted:

Do you have any substantive complaints? Which routing and state management solutions did you explore?

Yeah, it kind of sucks React doesn't prescribe a single way of doing global state management or routing and you're forced to make a choice from a multitude of satisfactory options. But "cursed"?

I don't mind investigating and choosing an option, but all the options had something weird going on (for state management the "weird" is that everyone still uses Redux/RTK when there are other, presumably more ergonomic, options).

I first looked at a minimal router, maybe https://github.com/molefrog/wouter and passed on it because I don't like the idea of defining routes inside components. I implementing TanStack Router with file-based routing and abandoned that because I didn't like how it dictated the app's organization, and it was a bit too magic. Now I'm on React Router with a createBrowserRouter config object and it almost works, except for not having a sane way of doing global navigation guards for login/auth state. Every example I saw involved redirecting the user inside a component after the point where the app had presumably made any additional network requests for that route. I ended up abusing a top level route with a check in the loader function (which doesn't provide access to route objects???) and a shouldRevalidate function to (maybe???) make it re-evaluate the loader on every child route change.

For reference, here's an entire Vue navigation guard implementation:
code:
let initialized = false

router.beforeEach(async (to, from) => {
  const userStore = useUserStore()
  if (!initialized) {
    // on first load, attempt to restore session from cookie using PocketBase's client SDK
    await userStore.restoreSession()
    initialized = true
  }
  if (!userStore.isLoggedIn && to.path !== '/login') {
    return '/login'
  } else if (userStore.isLoggedIn && to.path === '/login') {
    return '/thing-list'
  }
})
Redux doesn't allow async reducers, so I had to rethink how I was doing server requests and state management from the Vue app. This is kind of on me for not using a dedicated server state library, but my goal was to gently caress with Redux so that's what I did.

JSX on its own is fine I guess but doesn't seem to really provide much actual benefit over more HTML-styled components, and avoiding unnecessary re-renders is less of an issue in Vue.

pentium166
Oct 15, 2012
Also I think rendering an SPA on the backend introduces a huge amount of complexity and foot guns (leaking closures?), and if that's something you felt you had to reach for to reach your SEO or time to first paint goals or whatever, is a sign that your application was not a good fit for an SPA to begin with. But in the real world I guess you can't just throw out your entire frontend and rebuild it in Java or whatever, so here we are.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

pentium166 posted:

Redux doesn't allow async reducers

RTK comes with a querying solution:

https://redux-toolkit.js.org/rtk-query/overview#basic-usage


pentium166 posted:

Also I think rendering an SPA on the backend introduces a huge amount of complexity and foot guns (leaking closures?), and if that's something you felt you had to reach for to reach your SEO or time to first paint goals or whatever, is a sign that your application was not a good fit for an SPA to begin with.

It's honestly like any other thing. Once you learn and master it, it's fine.

SSR react can make your site 1MB vs SPA react being 6+MBs. There's a million benefits other than good SEO. But yeah the most optimal solution is always going to be use a non-javascript language to create your documents. But people like React better than writing PHP or Django, so here we are.

prom candy
Dec 16, 2005

Only I may dance

pentium166 posted:

I don't mind investigating and choosing an option, but all the options had something weird going on (for state management the "weird" is that everyone still uses Redux/RTK when there are other, presumably more ergonomic, options).

I first looked at a minimal router, maybe https://github.com/molefrog/wouter and passed on it because I don't like the idea of defining routes inside components. I implementing TanStack Router with file-based routing and abandoned that because I didn't like how it dictated the app's organization, and it was a bit too magic. Now I'm on React Router with a createBrowserRouter config object and it almost works, except for not having a sane way of doing global navigation guards for login/auth state. Every example I saw involved redirecting the user inside a component after the point where the app had presumably made any additional network requests for that route. I ended up abusing a top level route with a check in the loader function (which doesn't provide access to route objects???) and a shouldRevalidate function to (maybe???) make it re-evaluate the loader on every child route change.

For reference, here's an entire Vue navigation guard implementation:
code:
let initialized = false

router.beforeEach(async (to, from) => {
  const userStore = useUserStore()
  if (!initialized) {
    // on first load, attempt to restore session from cookie using PocketBase's client SDK
    await userStore.restoreSession()
    initialized = true
  }
  if (!userStore.isLoggedIn && to.path !== '/login') {
    return '/login'
  } else if (userStore.isLoggedIn && to.path === '/login') {
    return '/thing-list'
  }
})
Redux doesn't allow async reducers, so I had to rethink how I was doing server requests and state management from the Vue app. This is kind of on me for not using a dedicated server state library, but my goal was to gently caress with Redux so that's what I did.

JSX on its own is fine I guess but doesn't seem to really provide much actual benefit over more HTML-styled components, and avoiding unnecessary re-renders is less of an issue in Vue.

You should've asked in here for help/recs. I would've said if the state you're managing is mainly server state then just use react-query, and to just use React Router off the bat.

In terms of guarding routes, I've usually done that something like this:

code:
const user = useCurrentUser();

return (
  <Router>
    {user ? (
      <Switch>
        <Route path={"/"}><SomeAuthedComponent /></Route>
        <Route path="/hi"><SomeOtherThing /></Route>
      </Switch>
    ) : (
      <Switch>
        <Route path="/log-in"><LogIn /></Route>
        <Route path="/forgot-password"><ForgotPassword /></Route>
      </Switch>
    )}
  </Router>
)

dupersaurus
Aug 1, 2012

Futurism was an art movement where dudes were all 'CARS ARE COOL AND THE PAST IS FOR CHUMPS. LET'S DRAW SOME CARS.'

pentium166 posted:

JSX on its own is fine I guess but doesn't seem to really provide much actual benefit over more HTML-styled components, and avoiding unnecessary re-renders is less of an issue in Vue.

Just remember that “rendering” a react component (running render on a class component or calling a functional component) doesn’t inherently equal rendering to the DOM. You can render a component as much as you want and as long as the output doesn’t change then react isn’t going to do anything with it.

pentium166
Oct 15, 2012
ANYWAY, my problem is that the React ecosystem isn't doing anything better than the other options and in many cases is actually worse, because other framework/library authors have the benefit of seeing where the rough edges are and exploring different patterns. I'm also salty about the state of tech hiring currently because I clearly bet on the wrong horse in 2017 when I first Frankensteined Vue 2 into a Backbone app, and nearly every front end/full stack job posting wants 5+ years of professional experience with React and Redux specifically, as if the basic concepts of how to architect a modern JavaScript application aren't transferable.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

pentium166 posted:

ANYWAY, my problem is that the React ecosystem isn't doing anything better than the other options and in many cases is actually worse, because other framework/library authors have the benefit of seeing where the rough edges are and exploring different patterns. I'm also salty about the state of tech hiring currently because I clearly bet on the wrong horse in 2017 when I first Frankensteined Vue 2 into a Backbone app, and nearly every front end/full stack job posting wants 5+ years of professional experience with React and Redux specifically, as if the basic concepts of how to architect a modern JavaScript application aren't transferable.

:qqsay:

prom candy
Dec 16, 2005

Only I may dance
you think you backed the wrong horse? before i learned react i learned ember!

hey mom its 420
May 12, 2007

if you know all that stuff you can learn React really quickly by implementing a few side projects and then easily fake the 5+ years of experience.

also redux lol. it's just a big object and a reducer. everywhere I've seen it, it was used to create intertwined spaghetti messes of codebases, so because of that employers think it's a really important and hard to master library

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

prom candy posted:

you think you backed the wrong horse? before i learned react i learned ember!

I'm maintaining an ember app right now.

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


I still deal with jquery scattered all over the code. No modern frameworks for me.

prom candy
Dec 16, 2005

Only I may dance

Wheany posted:

I'm maintaining an ember app right now.

How is it? I dropped it forever after trying React for like 10 minutes but that was a long time ago.

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
It's a lot more react-like these days afaik. One-way binding ("data down, actions up"), some kind of virtual dom, I think. A lot more functional, less boilerplate-y. You still make separate templates and controllers, but you don't necessarily need to make separate js files for helpers and modifiers.

Our product uses an older version, so I'm not fully up to speed on the most modern features of the framework. But I have to give it credit for being very backwards compatible.

Adbot
ADBOT LOVES YOU

fsif
Jul 18, 2003

pentium166 posted:

ANYWAY, my problem is that the React ecosystem isn't doing anything better than the other options and in many cases is actually worse, because other framework/library authors have the benefit of seeing where the rough edges are and exploring different patterns. I'm also salty about the state of tech hiring currently because I clearly bet on the wrong horse in 2017 when I first Frankensteined Vue 2 into a Backbone app, and nearly every front end/full stack job posting wants 5+ years of professional experience with React and Redux specifically, as if the basic concepts of how to architect a modern JavaScript application aren't transferable.

I've used React for 7 or 8 years. Your view on React jives with mine. You're not crazy.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply