@@dealloc nothing that already exists would be changed or patched, it would be a brand new function to be called. The patch they're suggesting would break compatibility as it changes existing behavior. My suggestion would not and would give people the choice to keep using the regular date wherever appropriate but showing a console warning letting the developer know there may be side effects.
This is literally the EXACT same reasoning behind the fetch patch. No, it isn't bad just because it's a patch - *it's bad because it's forcing a function to lie.* And this is literally the SAME lie again - an implicitly cached value. The only difference is that instead of returning a cached URL response, we're returning a cached Date output. What is this obsession with forcing return values to support incorrect code, instead of encouraging people to write code that actually manages its own state correctly? If we need a single stable output, then it is the developer's responsibility to retrieve that output once and pass it directly to the other layers that need it - that goes for data fetching, dates, and countless other things. Also, it is up to the developer to decide whether the server OR the client is the source of truth for getting the value - not to assume that one is automatically correct and that they should be in agreement. Stop making functions lie.
Yeah, this. I'm mostly a C++ developer, so to me being explicit about things and not having things happen opaquely in the background without my intent or knowledge is a strong preference of mine. Then again, perhaps there is a case to be made for a framework being super basic and offering just a single way to do a thing and then doing a lot of magic in the background to ensure that it's the once and for all best and most optimal way to achieve the desired result. One could also argue that it's only mysterious and opaque and a "lie" if you don't read the documentation. All that said, I personally still prefer for fetch to work the way it does in the browsers, and for me to have the control to implement things the way I see fit. Maybe if you want to have a special cached fetch in the framework, name it something else that reflects its behavior.
@@0dWHOHWb0I don't think the designers of this could even make that argument in good faith, because the fact that it's implemented as a patch proves the intent. That is, to deliberately break the behavior of existing external code in order to "fix" their own concerns. In other words, this is breaking the contract of a dependency - which means _also_ breaking the contracts of any other functions that already depends on it - making them lie by extension. _Everything_ using time in the user code will now behave differently than before, depending on whether it happens to be called during the process of serving react content or not. It's a ridiculous band-aid solution to problems that shouldn't exist in the first place, because of flaws in the framework's design (requiring exactly matching view models between client and server, and not being able to pass data easily between layers).
Why does "it suck" that the serverside Date() spits out it's current date and the clientside Date() (if "use client" is stated) spits ITS current date out? To me this is expected... No? Like, I get that it's unfortunate and that red equals bad, but... that's just SSR things for you, no...? I feel like every potential change to "fix" this just introduces more harm than good. But oh well, we will see...
It is inconsistent with the hydration model. If you only rely purely on SSR vs. CSR then yes, that would be expected to be different results. But here we are dealing with hydration, which means that we expect the same initial state and output on both sides.
@@dealloc I mean, that's just the expectation of the developer(s) - no...? Who is "we" in that case? When I first encountered this behaviour (Nuxt.js, but I guess it's the same thing when it comes to this?), it was messy to debug but never did I feel this "issue" needs "fixing"...? To me this kind of looks like this wierd obsession of getting rid of red errors by changing the engine under the hood. If the time-delta between SSR and Hydration gets big, why should Date() have the "older" SSR Date on hydration...? At which point is this delta-time an actual dealbreaker? Is it ever? I don't know. And i don't really have a Horse in this race, because ultimately I don't really care anyway. So... to circle back to my point: The current behaviour makes sense to me even in terms of Hydration. I expect an error. I get an error.
@@deallocYou expect the client and server to match when you have pure functions and consistent output There is nothing pure about the Date constructor - it gives you different results each time you make one (unless you have an initial value you can pass in, which often isn't the case) That's the real source of the pain points - React's entire model (which is based on pure functions and snapshot-based state) is not compatible with common non-deterministic values developers would want to use for UIs
@@DubiousNachos So... this is where we disagree. My point is... I don't expect them to match in this specific case. To spell it out more bluntly: If I evaluate the time at different times I expect a mismatch....!? And a mismatch results in an error because my SSR stack is expecting a match. And that's whats happening, which is - atleast in my mind - the desired behaviour? Now is it a bit of a hassle? Yes. Sure... But as I said... that's just SSR things - you should be used to everything beeing a hassle by now.
It's stupid. It solves one of many issues, because you're hydrating with non-idempotent logic. What's next? Are they just going to patch anything that isn't idempotent lmao. SOLVE THE FUNDAMENTAL ISSUE.
@@foreshadowru then I guess those libraries will just have to use that function internally as well. Better than a library that doesn't know about this and would ABSOLUTELY NOT WORK WITH THIS CHANGE being irreversibly rugpulled, because THAT sounds like a breaking change.
Polyfills usually have checks that will apply them only if the target functionality is absent. In other words their initialization looks something like this: *window.something = checkForSomethingFunctionalitySomehow() ? window.something : somethingPolyfill;* At least its definetly how Array and Object static and prototype methods are applied, which makes sense, especially from the point of performance. Wouldn't it make more sense to create a separate *React.Date* object that would work the same way as original Date plus hydration fix? Adding *import { Date } from "react"* should be a pretty easy fix and most importantly its very obvious for everyone. I remember when I worked with Angular 1, provided its own function, like setTimeout, that could be injected into components and services via dependency injection.
Aren't polyfill by nature only patches when the feature does not exist? While technically does the same patching, it feels different as by design its meant to be not used when possible.
Tbh it sounds like they only patch it during hydration. So if you write your own js functions that are executed afterwards, you still have the normal Date functionality? Weird I guess, but less bad than I thought. Still feel like changing default js behaviour is unnecessarily dangerous
This is a valid compromise honestly. Because its hindering a functionality but it should be clearly communicated to devs as well. The patching of fetch was just plain bad idea.
9:18 - What a wild conclusion. I think you have some kind of brain fog. You effectively said that the framework forces you to do something to get around its hydration quirk and then said the solution is for the framework to deliberately implement another quirk to fix it. Maybe the framework should address the root issue, that it should have a better way to separate client and server values that are expected to be different?
Recently, I had the same issue but with Math.random(), and I don't really like the idea of patching js functions, because why only patch Date? Someone could say we should also patch Math.random(), but why stop there? I guess there are so many functions that can behave differently on server and client, so having some of those behave in different ways is weird for me. I think they should come up with some better way of fixing this.
I have a hot take: I think running the same logic *twice* (one on the server and then again on the client) just to render a page is over-engineering. HTMX is the way go (Not to be confused with XHTML), there's no need for a fat front-end framework that takes more than 5 seconds to load (I'm looking at you, Angular). Combine with some nice template engine on the server and you're all set.
@@vikingthedude with dates yes, but hydration errors is a new being, since the library has shared code between front and back, a less “modern” approach is separation of concerns and just let us do its own thing on client. Btw in that note “less modern” we did a full circle from php to separation to php in react/any other meta framework in js.
@@MaxFunoff It would be better to avoid SSR, like letting the backend provide the JSON or GraphQL and let the frontend deal with the UI/UX, the only excuse for using SSR is SEO, but does your app need SEO after the logging page? I bet not, the performance argument is a damn lie, if you cache the index.html + chucked your js files for each page + CDN, you would have a super fast app with low resource usage because all the rendering would be done in the client side. PS: Even doing that for SEO is quite debatable because the crawler can wait for the React app to render the data, if everything is cached it should be fast
@@victor95pc agree but i have to admit its much easier to deal with applications with less frontend states and not having to deal with frontend/backend exchanges, things ssr frameworks provide.
I would think rendering the time should mostly be relative to the browser's time zone. For such use cases it's totally useless to have the date of the SSR reflecting the time zone of the server. But hydration errors are a major reason to not use SSR. Translations break the site, password managers break the site, many other browser extensions that change page markup break the site. I really would like to have a video that diggs into how to easily deal with all of these situations. Without having to know upfront what kind of Chrome extensions the user will use.
The cycle is so funny how the "brilliant" kids of today resolve the same old solved problems from tech generations past, unwilling to search anything and insistent on putting their own fingerprints on their own solution, stubbornly insisting that the lessons learned from the past don't apply to them because of their genius and unwillingness to read about anything that predates them. Its like pre Y2K is groundhog day over and over and over and oveeerrrrrrrr... Vercel, React (who Vercel has been buying up like crazy and notice all the new BS!?), and so on. The hottest things in tech today are eerily reminiscent of decades ago now.
There is never a good reason to override a poorly behaved SDK feature, because someone in your tech stack will be dependent on the exact faulty behavior to function correctly. Instead you should raise an MR or ticket against the SDK
Now they are just trolling. Why would they think adding more moving parts is always the best solution? Can't wait for the Next.js browser to be released by Vercel, with it's own brand new JS Engine.
The most common hydration mismatches IMO have been caused by showing / hiding / switching components based on media queries. Your server has to assume some base client dimensions, and then the client will necessarily be different on first render (because not everyone has the same size device). The way we solved it in the past is to use an effect - hard-code the client size to the server value everywhere, including first render on the client, and then when the effect runs (after the client render) you force a re-render at the actual client size. No more hydration error.
But if you throw away hydration, why hydrate in the first place? Just render the thing instead of hydrating it, bots already got your meta-tags, the rest is for users
@@nazarshvets7501 because we render mobile-first (initial render targets smallest viewport breakpoint), if the user is mobile then it's faster for them. They're on a lower-powered device than a desktop user so makes sense to help them out a tiny bit. Besides, not everything is thrown away, it's only the placement of items that need to change if the layout changes significantly enough that CSS can't effectively handle it.
@@thekwoka4707 sometimes you just need to render a different component depending on your viewport. And other times you need to render the same component, but somewhere else in the DOM. CSS alone can't always do that.
I’m not currently working on a NextJS project so maybe this was fixed but I would get a hydration error bec I had a chrome extension (I believe LastPass) and once I turned it off the error would go away. I spent so much time looking through my code when it turns out it was just an extension.
Why are they so adamant to patch something. Their isn't any issue with Date(). It does what it should. Give you a hydration warning so that you as the developer can fix depending on your use case. Stop trying to take the power away from the devs. Any dev that complains needs to learn more about how it works and why it gave that error.
The situation being "fixed" here is bad code. Initializing a new date to the current time is an effect. We should not trigger effects in render like this
Okay, it sounds like their priblem. They are good at inventing tasks for them, that are useless for the world! SSR stands for what? SERVER Side Rendering, which is how it was working from the very beginning: we generated HTML fragments based on data available on the server and client side was supposed not to question that html much, just work with it. Reacts philosophy is out of scope here. For me that means, if React has issues with SSR in conceptual level, then it will no be used at all in such setup.
This isn't just React but any other framework that needs hydration. You can use React just for SSR and ignore all those stuff, but if you need to continue doing things on the client that is other paradigmn
NEVER modify CORE functions and apis. If you want to give an alternative, do seperately. NEVER OVERRIDE JACK SHIT! This is _MY_ project. _I_ will not tolerate some _stranger_ acting like they know better and taking over my code base without my permission. If I want to use your crap, I will do so explicitly. Sell me on using it and let me choose. Forcing it down my throat is the kind of thinking that is making everything shittier.
I know this isn't the same topic, but can we please update Date()? How does it not include like all the functionality of a day.js or date.fn yet? The specific nightmare I constantly run into is Date() and associated methods being so hell bent on making the date relative to the user's locale.
I think the main problem with dates is the timezone issue, as Indian i want my dates to be in IST (Indian standard time) and formatted DD/MM/YYYY but implementing that without hydration errors is a headache
One of my most common sources for this kind of error (other than datetime / timezone things) is client-specific stuff. For example if you have any layout code in JS (e.g. to polyfill container queries) or are rendering stuff out of local storage.
as a dev who was learning nextjs, one of my first things was a todo list using a daily list. when i deployed my app to vercel, it was in a different timezone and that led to a whole rabbithole that leads to a similar workaround that you used as passing the date to the client from server, but i opted for only running the date on client side and send that to the server. i dont want to have to run the comparisons there but i just wanted it to work D:
I get a hydration error when I put a button in a menu from shadcn because the menu itself is basically a button and nested buttons seem to cause that error
The first version of the page you load is more complete. It’s especially useful for SEO crawlers as they have a limited amount of compute and time. Honestly to me ISR is the least sucky solution for this but what do I know 🤷
an easier way to check what the server has returned is to right click anywhere on the document and choose "view page source", or use the shortcut Ctrl + U
Seeing this demo where you get a hydration error, I can't help but see this as a problem with React only. Something like a time meant for local display should never create an error, the best it could be is a warning to the developer that they might have written a bug if they intended the client to display the 'server' time but are actually displaying the 'client' time. This would be corrected by specifying a timezone explicitly, and then React should never do validation on the results of Date objects. It should be precisely the same thing as having a Math.random() call that runs on server and client, React should give a warning and then explain how they want you to be explicit on the intended behavior.
Or (hear me out), client components could be only that: components that run on the client. Exclusively. Why does the "use client" component run on the server? Why does it have to? If I wanted server component, then I wouldn't place a "use client" directive. What kind of abnormal behaviour is this?
Doesn't Next.js do these to send the HTML and CSS first and then hydrate it? And I think you can achieve a client only component with dynamic or lazy components
To optimize for first contentful paint and prevent sudden pop-in which is most common use-cases. For streaming HTML and selective hydration you can wrap client components in a Suspense.
@@neociber24 Well, I like the idea of having a built in routing system and an environment that is a bit opinionated, plus a "complete package" on how to take the whole .next directory, dockerize it and slam it in my infra. What I *don't* like is the fact that it has to SSR everything. Once again, "old" Next was very simple to that: you have "getServerrSideProps", it's SSR, you don't, it's classic create-react-app. I don't say it's better or worse. I say that the behaviour was *simple* and easy to work with. They should accommodate for these kind of scenarios too - instead the whole React ecosystem is dragged into this. Sigh.
Question, why does it suck for local time to be calculated where it's most relevant for the user? especially if they live somewhere with poor internet so there may be a minute or two between the local and server times for a page? And how would we display the local date and time in the client's timezone according to the client's machine after this change? Shouldn't date run only once on the client to avoid collision instead to provide the date correctly bound and formatted for the user?
I was more so hoping that they could also help unify other massive headaches of Date. Such as: > new Date("2024-01-01") Date Sun Dec 31 2023 19:00:00 GMT-0500 (Eastern Standard Time) > new Date("2024/01/01") Date Mon Jan 01 2024 00:00:00 GMT-0500 (Eastern Standard Time) But well,,, I guess for now, this will just be a dream
There are many ways to deal with this depending on what you want. new Date().toLocaleString() has 2 dependencies : the current time and the locale. You may want to use the current time of the server, for example to make sure it is in sync with some server-side stuff, but you will most likely want to use the user's locale. Whether you do any of this on the client side or the server side, you must acknowledge that there are 2 dependencies that make this call impure. You may for example get the locale and time zone from the client and render that on the server, it does not matter, but if you make side-effects visible in your code, or even in your type system, you will not be surprised by this kind of behaviour and you will have the luxury to deal with this in a number of ways. I heard Effect-TS have a React runtime now. I have no idea what they use it for and if it's compatible with server-side rendering but I would look it up. In any case, I would 9 times out of 10 prefer to take control of my side effects rather than depend on some spooky action at a distance by a third party.
I actually have a big issue with Hydration in my code, I always thought it was just a Nextjs problem....but it turns out that it's an overall React problem
So react is going to patch Date because Browsers don't give correct headers? Both Chrome and Firefox always sets "Accept-Language" to "en-US" even though my system is set to "en_DK.UTF-8" why not make the browsers respect the system settings and report that in the hearders?
Personally not a fan of the fetch patch - React and Solid Router's dedicated cache functions are better imo - but I could get onboard with this one. This date patch would _only_ happen on the client during hydration, in all other component executions Date would behave normally, so I'm guessing it'd be possible for a server time to be hydrated, before being quickly replaced by a different time generated on the client in a subsequent rerender. I'd say that's kinda the expected behaviour - if you server render a Date React should at least be able to hydrate that part properly, whether it gets replaced by a client-generated date in the future is your problem. At least the patch would be for internal behaviour that happens during a process you don't get control of - unlike the fetch patch which alters a user-facing API. Solid Router kinda does a similar thing with createAsync and Promise, where during hydration Promise will be patched to literally just be Promise.resolve, so that createAsync can re-run and hydrate without re-executing queries on the client after they've been done on the server.
Yes, this works for Promise and in principle this could work for Date too, but it won't work in practice because both client and server Date's are valid, so no matter which one you use as "source of truth" there will always be the other one that creates a conflict. In this case the Date that comes in via hydration will be completely unexpected and inconsistent with all successive dates that are created on the client.
I feel like we should enforce language versioning in the browser have the client script specify which version it's targeting, and have the browser adjust it's behavior for backwards compatibility rather than baking backwards compatibility into JS and living with that baggage
I really think the resumeability model is the right way forward. In my opinion running the same code on the backend and again in the frontend just to correctly attach event handlers is a bad idea. Makes the mental model more complex for no good reason
So, as I understood, we want to run impure function on different envs with different states connected to it and we expect that the result must be the same which is obviously impossible and we need to have sicret hack to achive this goal. Looks like the same will happen with Math.random.
As a Java dev looking in, I've come to the realisation on how much of a cluster f$ck the JS world is! I feel blessed that I've managed to avoid it for 32 years!
Patching things is very problematic. I just switched from jest to vitest, because when I run my code via jest `error instanceof Error` is always false and so all my error handling code breaks. They somehow patch all globals for some reason? I stopped investigating, I don't have the energy for that. vitest on the other hand segmentation faults all over the place unless I use --pool=forks. Well, at least I could make it work. Ugh. Why is it all so horrible in JavaScript land?
I hate the way jest patches globals. It takes away all power from the programmer, you’re at the mercy of jest. I like how vitest makes you import stuff instead of giving you globals
On the fence about this. I mean, it seems like it's not that big of a deal if it's only during hydration (I didn't like fetch because it was always there whenever you made a request, this just fixes one issue and then goes away). But I've never had date related hydration errors happen to me. As long as it doesn't mess with anything at runtime I'll get used to it (as in, forget it's an issue in the first place)
In my opinion, having this server-defined behavior on the client is not acceptable. Even when it's limited to hydration. This approach would need similar changes for ANY value that might be serialized differently on the client than on the server (so every localizable value basically). A way better approach would see a way to make the Hydration algorithm sensitive to these outputs and ignore / accept the differences in serialization output in these places. Use data-Attributes, marker comments, whatever floats your boat. But do not monkey patch serialization and localization features on the client to force them to output the same as the server. This is a rabbit hole we do not want to go into.
As developer of react app which is only using client side rendered components and quite allot of date.now and timedeltas, I really hope this patch does not have any effect on my code.
the first time i had one, the time it took me to understand it was kinda of annoying, i understood it because i was commenting out components one by one to figure out where this happened.
Next vid: we droping hydration because this browsers extentions are insane tbh: why spend time on hydration, when you know you would rerender anyway (dates, random, media-queries etc)?
Your date on the client should not depend on the date the server returned but I still don't know how it will be implemented. I don't care about patches if are explicit but trying make Date work different doesn't sounds good, we should just live with the problem and existent solutions
Why all these issues come with gaslighting the community? It is BS to say the caching default behavior of Next not being liked a issue of education... no... it's an issue of a team of people forcing one way of doing things that works for a set of use cases to everyone. It does feel like React is riding fast towards a "Angular" phase.
Most of my web development is in support of a rather technically illiterate user base. We're talking I was supporting all the way back to Netscape Navigator 4.0 until a few years ago, and I still have to adapt to one user with a web browser that doesn't support TLS1.1. When I do progressive enhancements that are time-based, I try to say "event X is happening in Y seconds" rather than "at time Z" because I can't even count on the computers having the right time set. And yes, the person that pays me is probably the biggest offender. That said, I can appreciate the way they're doing this. It won't help if the user's clock is wrong, but it handles just about everything else. I can just see unpatched React complaining because a dialup user's web browser took a few seconds to even start to hydrate.
This is getting crazy. No, you can't patch every platform API to fix newbie problems. Never a good idea. Just provide utilities, linting rules etc. to teach the best practices.
If you have hydration issues, you need to learn why it's happening and how to fix it. Overriding behavior just so beginners don't get confused is not a valid reason to change it.
They should instead add their own date that explicitly specifies server or client date and warn devs in the console if the regular date is used.
That would break backwards compatibility with existing React components/libraries that rely on Date API and is rendered in SSR and hydrated on client.
@@deallocno it won’t, the comment states exactly the opposite of breaking, react team will introduce breaking change with that patch
@@dealloc nothing that already exists would be changed or patched, it would be a brand new function to be called.
The patch they're suggesting would break compatibility as it changes existing behavior. My suggestion would not and would give people the choice to keep using the regular date wherever appropriate but showing a console warning letting the developer know there may be side effects.
because that will require all libraries that use Date internally to do so as well, or will required you not to use those libraries
useDate
This is literally the EXACT same reasoning behind the fetch patch. No, it isn't bad just because it's a patch - *it's bad because it's forcing a function to lie.* And this is literally the SAME lie again - an implicitly cached value. The only difference is that instead of returning a cached URL response, we're returning a cached Date output. What is this obsession with forcing return values to support incorrect code, instead of encouraging people to write code that actually manages its own state correctly? If we need a single stable output, then it is the developer's responsibility to retrieve that output once and pass it directly to the other layers that need it - that goes for data fetching, dates, and countless other things. Also, it is up to the developer to decide whether the server OR the client is the source of truth for getting the value - not to assume that one is automatically correct and that they should be in agreement. Stop making functions lie.
preach
Yeah, this. I'm mostly a C++ developer, so to me being explicit about things and not having things happen opaquely in the background without my intent or knowledge is a strong preference of mine. Then again, perhaps there is a case to be made for a framework being super basic and offering just a single way to do a thing and then doing a lot of magic in the background to ensure that it's the once and for all best and most optimal way to achieve the desired result. One could also argue that it's only mysterious and opaque and a "lie" if you don't read the documentation. All that said, I personally still prefer for fetch to work the way it does in the browsers, and for me to have the control to implement things the way I see fit. Maybe if you want to have a special cached fetch in the framework, name it something else that reflects its behavior.
@@0dWHOHWb0I don't think the designers of this could even make that argument in good faith, because the fact that it's implemented as a patch proves the intent. That is, to deliberately break the behavior of existing external code in order to "fix" their own concerns. In other words, this is breaking the contract of a dependency - which means _also_ breaking the contracts of any other functions that already depends on it - making them lie by extension. _Everything_ using time in the user code will now behave differently than before, depending on whether it happens to be called during the process of serving react content or not. It's a ridiculous band-aid solution to problems that shouldn't exist in the first place, because of flaws in the framework's design (requiring exactly matching view models between client and server, and not being able to pass data easily between layers).
Still just a library btw.
LOL
Next.js is just an npm package
our planet is just a rock suspended in the void
Why does "it suck" that the serverside Date() spits out it's current date and the clientside Date() (if "use client" is stated) spits ITS current date out?
To me this is expected... No? Like, I get that it's unfortunate and that red equals bad, but... that's just SSR things for you, no...?
I feel like every potential change to "fix" this just introduces more harm than good. But oh well, we will see...
It is inconsistent with the hydration model. If you only rely purely on SSR vs. CSR then yes, that would be expected to be different results. But here we are dealing with hydration, which means that we expect the same initial state and output on both sides.
@@dealloc
I mean, that's just the expectation of the developer(s) - no...?
Who is "we" in that case?
When I first encountered this behaviour (Nuxt.js, but I guess it's the same thing when it comes to this?), it was messy to debug but never did I feel this "issue" needs "fixing"...?
To me this kind of looks like this wierd obsession of getting rid of red errors by changing the engine under the hood. If the time-delta between SSR and Hydration gets big, why should Date() have the "older" SSR Date on hydration...? At which point is this delta-time an actual dealbreaker? Is it ever?
I don't know. And i don't really have a Horse in this race, because ultimately I don't really care anyway.
So... to circle back to my point: The current behaviour makes sense to me even in terms of Hydration. I expect an error. I get an error.
@@Scereyei agree
@@deallocYou expect the client and server to match when you have pure functions and consistent output
There is nothing pure about the Date constructor - it gives you different results each time you make one (unless you have an initial value you can pass in, which often isn't the case)
That's the real source of the pain points - React's entire model (which is based on pure functions and snapshot-based state) is not compatible with common non-deterministic values developers would want to use for UIs
@@DubiousNachos
So... this is where we disagree. My point is... I don't expect them to match in this specific case.
To spell it out more bluntly: If I evaluate the time at different times I expect a mismatch....!?
And a mismatch results in an error because my SSR stack is expecting a match.
And that's whats happening, which is - atleast in my mind - the desired behaviour?
Now is it a bit of a hassle? Yes. Sure... But as I said... that's just SSR things - you should be used to everything beeing a hassle by now.
They should just add a `useDate` hook that you can use that just gives you a date object with the date that was created on the server.
Agree
It's stupid. It solves one of many issues, because you're hydrating with non-idempotent logic. What's next? Are they just going to patch anything that isn't idempotent lmao. SOLVE THE FUNDAMENTAL ISSUE.
Why not make a new function and utilise that on server and client?
because that will require all libraries that use Date internally to do so as well, or will required you not to use those libraries
Same reason as why they patched fetch
@@foreshadowru then I guess those libraries will just have to use that function internally as well. Better than a library that doesn't know about this and would ABSOLUTELY NOT WORK WITH THIS CHANGE being irreversibly rugpulled, because THAT sounds like a breaking change.
Hurray, new footguns to stick in the holes in the old ones shot 🙄
Next up: We’re patching Math.random()
Polyfills usually have checks that will apply them only if the target functionality is absent. In other words their initialization looks something like this:
*window.something = checkForSomethingFunctionalitySomehow() ? window.something : somethingPolyfill;*
At least its definetly how Array and Object static and prototype methods are applied, which makes sense, especially from the point of performance.
Wouldn't it make more sense to create a separate *React.Date* object that would work the same way as original Date plus hydration fix? Adding *import { Date } from "react"* should be a pretty easy fix and most importantly its very obvious for everyone. I remember when I worked with Angular 1, provided its own function, like setTimeout, that could be injected into components and services via dependency injection.
Aren't polyfill by nature only patches when the feature does not exist? While technically does the same patching, it feels different as by design its meant to be not used when possible.
Nice, so they are going to break formatting by locale in the browser and timezones...
I'm sure they've thought of that
IMO something like this should marked by an eslint plugin...
It's a dumb idea.
Tbh it sounds like they only patch it during hydration. So if you write your own js functions that are executed afterwards, you still have the normal Date functionality? Weird I guess, but less bad than I thought.
Still feel like changing default js behaviour is unnecessarily dangerous
This is a valid compromise honestly. Because its hindering a functionality but it should be clearly communicated to devs as well. The patching of fetch was just plain bad idea.
Oh so its a transient thing? Damn
9:18 - What a wild conclusion. I think you have some kind of brain fog. You effectively said that the framework forces you to do something to get around its hydration quirk and then said the solution is for the framework to deliberately implement another quirk to fix it. Maybe the framework should address the root issue, that it should have a better way to separate client and server values that are expected to be different?
This is Vercel making changes to React that they feel is convenient to them. Nothing more. Next is eating React.
They will literally resurrect Angular with how much they change stuff.
that awkward moment when you record a whole video stanning a decision, only to realize you misread/misinterpreted the original tweet. lmao smh
Recently, I had the same issue but with Math.random(), and I don't really like the idea of patching js functions, because why only patch Date? Someone could say we should also patch Math.random(), but why stop there? I guess there are so many functions that can behave differently on server and client, so having some of those behave in different ways is weird for me. I think they should come up with some better way of fixing this.
Oh boy, can't wait to see all the confusion this will cause across timezones
The “hydration error” that took me way too long to figure out was just Last Pass adding stuff to my login page.
I have a hot take: I think running the same logic *twice* (one on the server and then again on the client) just to render a page is over-engineering. HTMX is the way go (Not to be confused with XHTML), there's no need for a fat front-end framework that takes more than 5 seconds to load (I'm looking at you, Angular). Combine with some nice template engine on the server and you're all set.
This seems like a problem with Next's design that they should solve rather than changing Date.
The thing about dates is that you dont really need server date but client date
The more we go forward the more Im convinced that JS shouldn’t be on server
I've always felt that way. Too many devs have stockholm syndrome when it comes to JS and have a need to use it for EVERYTHING!!!!
This would be an issue no matter the language no? Its due to the fact that we have timezones. A true solution would be a one world order
@@vikingthedude with dates yes, but hydration errors is a new being, since the library has shared code between front and back, a less “modern” approach is separation of concerns and just let us do its own thing on client.
Btw in that note “less modern” we did a full circle from php to separation to php in react/any other meta framework in js.
@@MaxFunoff It would be better to avoid SSR, like letting the backend provide the JSON or GraphQL and let the frontend deal with the UI/UX, the only excuse for using SSR is SEO, but does your app need SEO after the logging page? I bet not, the performance argument is a damn lie, if you cache the index.html + chucked your js files for each page + CDN, you would have a super fast app with low resource usage because all the rendering would be done in the client side.
PS: Even doing that for SEO is quite debatable because the crawler can wait for the React app to render the data, if everything is cached it should be fast
@@victor95pc agree but i have to admit its much easier to deal with applications with less frontend states and not having to deal with frontend/backend exchanges, things ssr frameworks provide.
I would think rendering the time should mostly be relative to the browser's time zone. For such use cases it's totally useless to have the date of the SSR reflecting the time zone of the server.
But hydration errors are a major reason to not use SSR. Translations break the site, password managers break the site, many other browser extensions that change page markup break the site.
I really would like to have a video that diggs into how to easily deal with all of these situations. Without having to know upfront what kind of Chrome extensions the user will use.
Glad i am not using react and nextjs anymore
So what do you use now
If only use React you wouldn't get these problem, but ppl buy into SSR crap super hard
@@victor95pc SSR is really good, just not with javascript. You shouldn't use javascript for this, especially react.
@@victor95pc imagine having to use useEffect every other component
@@victor95pc Some people need SEO
RNG is next
rng?
@@bhumit070 random number generator
@@bhumit070 random number generation
lol
🤣
The cycle is so funny how the "brilliant" kids of today resolve the same old solved problems from tech generations past, unwilling to search anything and insistent on putting their own fingerprints on their own solution, stubbornly insisting that the lessons learned from the past don't apply to them because of their genius and unwillingness to read about anything that predates them. Its like pre Y2K is groundhog day over and over and over and oveeerrrrrrrr... Vercel, React (who Vercel has been buying up like crazy and notice all the new BS!?), and so on. The hottest things in tech today are eerily reminiscent of decades ago now.
Just because something provokes the same feelings in you doesn’t mean it’s the same thing… Nice rant
@@BeBoBE it's the same techniques with the same results and pitfalls. Just because you're young doesn't mean old problems don't apply to you
There is never a good reason to override a poorly behaved SDK feature, because someone in your tech stack will be dependent on the exact faulty behavior to function correctly. Instead you should raise an MR or ticket against the SDK
Maybe the problem is trying so hard to make code run on both the client and the server.
Running non deterministic code twice, trying to get the same result both times. We’re playing with fire here
Now they are just trolling. Why would they think adding more moving parts is always the best solution?
Can't wait for the Next.js browser to be released by Vercel, with it's own brand new JS Engine.
The most common hydration mismatches IMO have been caused by showing / hiding / switching components based on media queries. Your server has to assume some base client dimensions, and then the client will necessarily be different on first render (because not everyone has the same size device). The way we solved it in the past is to use an effect - hard-code the client size to the server value everywhere, including first render on the client, and then when the effect runs (after the client render) you force a re-render at the actual client size. No more hydration error.
But if you throw away hydration, why hydrate in the first place? Just render the thing instead of hydrating it, bots already got your meta-tags, the rest is for users
@@nazarshvets7501 because we render mobile-first (initial render targets smallest viewport breakpoint), if the user is mobile then it's faster for them. They're on a lower-powered device than a desktop user so makes sense to help them out a tiny bit.
Besides, not everything is thrown away, it's only the placement of items that need to change if the layout changes significantly enough that CSS can't effectively handle it.
@@BeheadedKamikazegood solution with solid logic though it feels very silly that y’all are forced to do something like this at all
you shouldn't have that handled by js though.
Thats a job for css
@@thekwoka4707 sometimes you just need to render a different component depending on your viewport. And other times you need to render the same component, but somewhere else in the DOM. CSS alone can't always do that.
I’m not currently working on a NextJS project so maybe this was fixed but I would get a hydration error bec I had a chrome extension (I believe LastPass) and once I turned it off the error would go away. I spent so much time looking through my code when it turns out it was just an extension.
I’ve seen a lot of hydration errors caused by invalid HTML (e.g. div inside a p tag). Is there a polyfill for devs knowing what they’re doing?
What use do you have for this?
Hydration error, I think Gatorade would solve that.
Why are they so adamant to patch something. Their isn't any issue with Date(). It does what it should. Give you a hydration warning so that you as the developer can fix depending on your use case. Stop trying to take the power away from the devs. Any dev that complains needs to learn more about how it works and why it gave that error.
The situation being "fixed" here is bad code. Initializing a new date to the current time is an effect. We should not trigger effects in render like this
The difference to polyfills is, though: If the polyfill isn't necessary on a client, it won't be polyfilled. Patching *alway* changes things.
Okay, it sounds like their priblem.
They are good at inventing tasks for them, that are useless for the world!
SSR stands for what? SERVER Side Rendering, which is how it was working from the very beginning: we generated HTML fragments based on data available on the server and client side was supposed not to question that html much, just work with it. Reacts philosophy is out of scope here. For me that means, if React has issues with SSR in conceptual level, then it will no be used at all in such setup.
This isn't just React but any other framework that needs hydration.
You can use React just for SSR and ignore all those stuff, but if you need to continue doing things on the client that is other paradigmn
@@neociber24 Why hydrate when you can just rerender? (you never gonna escape browser extensions which mess with your html)
I get alot of hydration errors related to p tags
Move to CSR, it will be solved haha
We should patch p tags too
Probably incorrect HTML, placing divs inside p tags etc...
@@lucafelix nah it was with li tags... But maybe I am to stupid... That's at least how I feel haha
After hydration, just p normally, don't tag with it, that's the error.
The thing I love the most about React is the amount of footguns you have access to. Great that they add even more of those!
That said, this makes much more sense then the frankly ridiculous fetch thing
Please, list them all! It would be fun :D
Like: useEffect for infinite loops, pathing global Date() for confused JS users. What else?
NEVER modify CORE functions and apis. If you want to give an alternative, do seperately. NEVER OVERRIDE JACK SHIT!
This is _MY_ project.
_I_ will not tolerate some _stranger_ acting like they know better and taking over my code base without my permission.
If I want to use your crap, I will do so explicitly.
Sell me on using it and let me choose. Forcing it down my throat is the kind of thinking that is making everything shittier.
I know this isn't the same topic, but can we please update Date()? How does it not include like all the functionality of a day.js or date.fn yet? The specific nightmare I constantly run into is Date() and associated methods being so hell bent on making the date relative to the user's locale.
Look at the Temporal TC39 Proposal ❤
Just curious won't this patch become obsolete once temporals is introduced in js?
I think the main problem with dates is the timezone issue, as Indian i want my dates to be in IST (Indian standard time) and formatted DD/MM/YYYY but implementing that without hydration errors is a headache
Why does the date function needs to run both on the server and on the client when you use 'use client'? Does it make sense?
One of my most common sources for this kind of error (other than datetime / timezone things) is client-specific stuff. For example if you have any layout code in JS (e.g. to polyfill container queries) or are rendering stuff out of local storage.
as a dev who was learning nextjs, one of my first things was a todo list using a daily list. when i deployed my app to vercel, it was in a different timezone and that led to a whole rabbithole that leads to a similar workaround that you used as passing the date to the client from server, but i opted for only running the date on client side and send that to the server. i dont want to have to run the comparisons there but i just wanted it to work D:
I get a hydration error when I put a button in a menu from shadcn because the menu itself is basically a button and nested buttons seem to cause that error
Is using the “suppressHydrationWarning” prop in React okay when working with dates? If not, how else would you tackle the issue?
How can running the code twice and matching the HTML be more effective than before when we just ran the code on the client and attached it
The first version of the page you load is more complete. It’s especially useful for SEO crawlers as they have a limited amount of compute and time. Honestly to me ISR is the least sucky solution for this but what do I know 🤷
an easier way to check what the server has returned is to right click anywhere on the document and choose "view page source", or use the shortcut Ctrl + U
Seeing this demo where you get a hydration error, I can't help but see this as a problem with React only. Something like a time meant for local display should never create an error, the best it could be is a warning to the developer that they might have written a bug if they intended the client to display the 'server' time but are actually displaying the 'client' time. This would be corrected by specifying a timezone explicitly, and then React should never do validation on the results of Date objects. It should be precisely the same thing as having a Math.random() call that runs on server and client, React should give a warning and then explain how they want you to be explicit on the intended behavior.
Or (hear me out), client components could be only that: components that run on the client. Exclusively. Why does the "use client" component run on the server? Why does it have to? If I wanted server component, then I wouldn't place a "use client" directive. What kind of abnormal behaviour is this?
Doesn't Next.js do these to send the HTML and CSS first and then hydrate it?
And I think you can achieve a client only component with dynamic or lazy components
To optimize for first contentful paint and prevent sudden pop-in which is most common use-cases. For streaming HTML and selective hydration you can wrap client components in a Suspense.
That's a missunderstanding.
Client component are just componentes that are hydrated.
If you don't want components that run on server use "dynamic" or don't use a SSR framework.
@@neociber24 Well, I like the idea of having a built in routing system and an environment that is a bit opinionated, plus a "complete package" on how to take the whole .next directory, dockerize it and slam it in my infra. What I *don't* like is the fact that it has to SSR everything.
Once again, "old" Next was very simple to that: you have "getServerrSideProps", it's SSR, you don't, it's classic create-react-app. I don't say it's better or worse. I say that the behaviour was *simple* and easy to work with.
They should accommodate for these kind of scenarios too - instead the whole React ecosystem is dragged into this. Sigh.
Question, why does it suck for local time to be calculated where it's most relevant for the user? especially if they live somewhere with poor internet so there may be a minute or two between the local and server times for a page? And how would we display the local date and time in the client's timezone according to the client's machine after this change? Shouldn't date run only once on the client to avoid collision instead to provide the date correctly bound and formatted for the user?
I was more so hoping that they could also help unify other massive headaches of Date. Such as:
> new Date("2024-01-01")
Date Sun Dec 31 2023 19:00:00 GMT-0500 (Eastern Standard Time)
> new Date("2024/01/01")
Date Mon Jan 01 2024 00:00:00 GMT-0500 (Eastern Standard Time)
But well,,, I guess for now, this will just be a dream
I am sorry but this is so stupid. It's called a side-effect and there are means to manage them.
Like only running the date on the client.
There are many ways to deal with this depending on what you want. new Date().toLocaleString() has 2 dependencies : the current time and the locale. You may want to use the current time of the server, for example to make sure it is in sync with some server-side stuff, but you will most likely want to use the user's locale. Whether you do any of this on the client side or the server side, you must acknowledge that there are 2 dependencies that make this call impure. You may for example get the locale and time zone from the client and render that on the server, it does not matter, but if you make side-effects visible in your code, or even in your type system, you will not be surprised by this kind of behaviour and you will have the luxury to deal with this in a number of ways.
I heard Effect-TS have a React runtime now. I have no idea what they use it for and if it's compatible with server-side rendering but I would look it up.
In any case, I would 9 times out of 10 prefer to take control of my side effects rather than depend on some spooky action at a distance by a third party.
I actually have a big issue with Hydration in my code, I always thought it was just a Nextjs problem....but it turns out that it's an overall React problem
Couldn't we just exclude date from SSR rendering alltogether
Lastpass modifying inputs was causing same hydration issues in my experience. That was a really dumb thing to debug
So react is going to patch Date because Browsers don't give correct headers? Both Chrome and Firefox always sets "Accept-Language" to "en-US" even though my system is set to "en_DK.UTF-8"
why not make the browsers respect the system settings and report that in the hearders?
This video is also one of the best explanations for hydration errors I've ever seen
Personally not a fan of the fetch patch - React and Solid Router's dedicated cache functions are better imo - but I could get onboard with this one.
This date patch would _only_ happen on the client during hydration, in all other component executions Date would behave normally, so I'm guessing it'd be possible for a server time to be hydrated, before being quickly replaced by a different time generated on the client in a subsequent rerender.
I'd say that's kinda the expected behaviour - if you server render a Date React should at least be able to hydrate that part properly, whether it gets replaced by a client-generated date in the future is your problem. At least the patch would be for internal behaviour that happens during a process you don't get control of - unlike the fetch patch which alters a user-facing API.
Solid Router kinda does a similar thing with createAsync and Promise, where during hydration Promise will be patched to literally just be Promise.resolve, so that createAsync can re-run and hydrate without re-executing queries on the client after they've been done on the server.
Yes, this works for Promise and in principle this could work for Date too, but it won't work in practice because both client and server Date's are valid, so no matter which one you use as "source of truth" there will always be the other one that creates a conflict. In this case the Date that comes in via hydration will be completely unexpected and inconsistent with all successive dates that are created on the client.
Regardless of my thoughts on Date, you did a fantastic job explaining hydration errors here that I think is super helpful and educational.
I feel like we should enforce language versioning in the browser
have the client script specify which version it's targeting, and have the browser adjust it's behavior for backwards compatibility
rather than baking backwards compatibility into JS and living with that baggage
They are so invested in ssr rehydration, that nothing seems wrong to them anymore
The road to hell...
I really think the resumeability model is the right way forward. In my opinion running the same code on the backend and again in the frontend just to correctly attach event handlers is a bad idea. Makes the mental model more complex for no good reason
So, as I understood, we want to run impure function on different envs with different states connected to it and we expect that the result must be the same which is obviously impossible and we need to have sicret hack to achive this goal.
Looks like the same will happen with Math.random.
As a Java dev looking in, I've come to the realisation on how much of a cluster f$ck the JS world is! I feel blessed that I've managed to avoid it for 32 years!
public static void main string args
@@PanosPitsi tab + psvm
@@PanosPitsi You can now do "void main() {}". Do keep up :)
Patching things is very problematic. I just switched from jest to vitest, because when I run my code via jest `error instanceof Error` is always false and so all my error handling code breaks. They somehow patch all globals for some reason? I stopped investigating, I don't have the energy for that. vitest on the other hand segmentation faults all over the place unless I use --pool=forks. Well, at least I could make it work. Ugh. Why is it all so horrible in JavaScript land?
I hate the way jest patches globals. It takes away all power from the programmer, you’re at the mercy of jest. I like how vitest makes you import stuff instead of giving you globals
@@vikingthedude Exactly!
On the fence about this. I mean, it seems like it's not that big of a deal if it's only during hydration (I didn't like fetch because it was always there whenever you made a request, this just fixes one issue and then goes away). But I've never had date related hydration errors happen to me. As long as it doesn't mess with anything at runtime I'll get used to it (as in, forget it's an issue in the first place)
Didn't know about resumability, but it seems more logical to me, why would you regenerate the HTML just to link things, ids are exactly for that.
The tech debt behind is unimaginably deep and unrecoverable.
couldn't they just lint converting dates to string in SSR and before hydration?
I mean the actual problem is mishandling of data
In my opinion, having this server-defined behavior on the client is not acceptable. Even when it's limited to hydration.
This approach would need similar changes for ANY value that might be serialized differently on the client than on the server (so every localizable value basically).
A way better approach would see a way to make the Hydration algorithm sensitive to these outputs and ignore / accept the differences in serialization output in these places.
Use data-Attributes, marker comments, whatever floats your boat. But do not monkey patch serialization and localization features on the client to force them to output the same as the server.
This is a rabbit hole we do not want to go into.
As a leptos user, I am an expert in Hydration Errors!
If you test your date function win new Date() inside a unit test, you can get a failed scenario (80% of cases, I guess). Milliseconds...
As developer of react app which is only using client side rendered components and quite allot of date.now and timedeltas, I really hope this patch does not have any effect on my code.
the first time i had one, the time it took me to understand it was kinda of annoying,
i understood it because i was commenting out components one by one to figure out where this happened.
React is its own meta language at this point
standards ? Does this mean : Binary code patch
Next vid: we droping hydration because this browsers extentions are insane
tbh: why spend time on hydration, when you know you would rerender anyway (dates, random, media-queries etc)?
Your date on the client should not depend on the date the server returned but I still don't know how it will be implemented.
I don't care about patches if are explicit but trying make Date work different doesn't sounds good, we should just live with the problem and existent solutions
Educational for low/medium skilled React devs / web devs in general using a js framework!
So are people still going to push the idea that react is just a framework?
Sweet mother of god. That's insane. React is going crazier and crazier.
You should read Artem Zakharchenko article on Why Patching Globals Is Harmful could be good balance
Just don't use js on the backend
The React team is turning into a source of memes...
I'm still not sure why React is so popular.
I guess its because it has a stronghold in SPA market and a lot of libraries? Plus JSX is cool ( I know about Solid).
Why all these issues come with gaslighting the community? It is BS to say the caching default behavior of Next not being liked a issue of education... no... it's an issue of a team of people forcing one way of doing things that works for a set of use cases to everyone. It does feel like React is riding fast towards a "Angular" phase.
Most of my web development is in support of a rather technically illiterate user base. We're talking I was supporting all the way back to Netscape Navigator 4.0 until a few years ago, and I still have to adapt to one user with a web browser that doesn't support TLS1.1. When I do progressive enhancements that are time-based, I try to say "event X is happening in Y seconds" rather than "at time Z" because I can't even count on the computers having the right time set. And yes, the person that pays me is probably the biggest offender.
That said, I can appreciate the way they're doing this. It won't help if the user's clock is wrong, but it handles just about everything else. I can just see unpatched React complaining because a dialup user's web browser took a few seconds to even start to hydrate.
This is getting crazy. No, you can't patch every platform API to fix newbie problems. Never a good idea. Just provide utilities, linting rules etc. to teach the best practices.
Easy fix:
Stop doing hydration
Do resumability
Qwik did it already.
If you have hydration issues, you need to learn why it's happening and how to fix it. Overriding behavior just so beginners don't get confused is not a valid reason to change it.
Stuff like this makes me want to learn quik
It's soo dumb, yk what's the best way to fix this issue is just use server side rendering.
No. The solution needs to be a Js standard.
Dates should only ever be client rendered