No joke, I'm switching to remix after this bug

  Рет қаралды 27,741

Web Dev Cody

Web Dev Cody

Күн бұрын

Пікірлер: 222
@WebDevCody
@WebDevCody Жыл бұрын
After getting help from another twitch streamer www.twitch.tv/fredkisss, it turns out that useOptimistic is the preferred solution, and it has to be used a specific way. I was doing this in my code (which didn't work) const [names, removeName] = useOptimistic( initialNames, (cur, name) => cur.filter((n) => n !== name) ); // in jsx { removeName(name); removeNameAction(name); }} > but instead I needed to do this: const [names, setNames] = useOptimistic( initialNames, (cur, newNames) => newNames ); // in jsx { setNames(names.filter((n) => n !== name)); removeNameAction(name); }} > for some reason, we can't have the filter occur inside the useOptimistic 🤷‍♂
@deeperlayer
@deeperlayer Жыл бұрын
your method works! it happens that i reused it in the code i sent you... you can use filters no problem no wonder you hated next so many opinions very little documentation
@lifeofcode
@lifeofcode Жыл бұрын
Thanks for the update Cody, this was bugging me all day today, playing with this (as I also juggle tickets at work lol) SO satisfying to find a real solution.
@mertdr
@mertdr Жыл бұрын
Thanks for sharing it! But it means that Next 13 doesn’t have a problem in the first place. An experimental feature, server actions (alpha), requires an expermental hook to work correctly in the app life cycle. I would call this a missing explanation or lack of documentation rather than a bug. Probably this should be reported to vercel to improve their documentation. Also I appreciate your and other devs efforts what makes next community vibrant and move forward faster.
@ubonginyang1889
@ubonginyang1889 Жыл бұрын
I've always maintained that remix is a much better option. I look forward to your remix videos😅
@thegrumpydeveloper
@thegrumpydeveloper Жыл бұрын
Would love to see how remix could actually solve this problem. I’m not seeing it because the response of the server is out of synch with the db. The same thing would happen if we pushed out the data update to an hour in the future. The server is out of sync with the data that was just posted. an optimistic update AND no refetch triggered would solve this but it’s imperfect without a local cache that overrides what we know is invalid data on the db.
@danihv
@danihv Жыл бұрын
I know that this is a simplified reproduction of the issue, but I usually prefer to have a 'blacklist approach' when doing client-side removing (doesn't matter if we are talking about local-only data or in this case, an optimistic update), and instead of storing the component data prop in a local state, I store an array of unique ids that i don't want to show, and then i filter the data (with memo if needed) and render the result. In this way you: 1- don't have to store duplicated information (both the parent "state data" that is being passing down as prop, and the local state), and 2- if prop changes, you dont need to have extra effects to update your local state, since you are storing only a blacklist (again, an array of uniques ids) I think that an approach like this will solve your issue, since looks like this is "stale while revalidate" behaviour
@ChristianNaths
@ChristianNaths Жыл бұрын
THIS. The issue is that useState is being used incorrectly-the initial state argument is not intended to update the state after the initial render. Much better to take this blacklist approach suggested here, where you track only the unique identifiers of the items you want to optimistically remove from the list 👍👍👍 Tracking multiple copies of the same state makes your program more complex than it need to be.
@balduin_b4334
@balduin_b4334 Жыл бұрын
thank you for that input! I think that is pretty smart :D
@fawwazAlharbi
@fawwazAlharbi Жыл бұрын
Already Switched to Remix and I'm very glad I did, I was reluctant at first because I know there will be a learning curve but my god things with the app router are too frustrating. I want to spend my time building stuff not fighting with the framework.
@xxXXuser69420XXxx
@xxXXuser69420XXxx Жыл бұрын
I absolutely hate Next 13 but every time you go into Vercel's videos or subreddit everyone is praising the app router... I'm guessing shills/bots
@WebDevCody
@WebDevCody Жыл бұрын
​@@xxXXuser69420XXxx I honestly don't think anyone is building anything that has real users or is interactive. You'll hit these strange issues the moment you start building anything useful. So far i've built 3 different apps using the app router, the code racer app, a tennis match making app, and a photo album app. If you just put "use client" at the top of every file, you'll be good for the most part 😆. Imagine having an API endpoint which requires developers to export dynamic = 'force-dynamic'. Like why do I need to export that for an API ENDPOINT?
@IvanRandomDude
@IvanRandomDude Жыл бұрын
@@xxXXuser69420XXxx Just people who don't work on anything more complex than TODO apps and "Twitter clones". Sure, the fact that Vercel has great marketing and has a lots of dev content creators in their pocket also helps.
@fs3120ch
@fs3120ch Жыл бұрын
I use Next 13, but I hate app router so I still use pages. Much simpler for me
@mskzzz
@mskzzz Жыл бұрын
@@WebDevCody I guess Next 13 is mostly about building SSR/SSG for low interactivity and use React/JSX as a templating language, with Next's file router system. However I don't think it's very far from being much better than Remix, I quite enjoy the new router I just think it lacks something to transform server action responses into cache updates
@darialyphia
@darialyphia Жыл бұрын
That's just crazy, Vercel is like the Blizzard of webdev at this point
@WebDevCody
@WebDevCody Жыл бұрын
🤣it's just not meant for simp devs like me
@mtin79
@mtin79 Жыл бұрын
Switched from nextjs to „remix run“ a while ago and never looked back
@Lorfv
@Lorfv Жыл бұрын
Cant wait for that remix video!
@AliyAkhbar
@AliyAkhbar Жыл бұрын
How about using tan stack query? 🤔
@cas818028
@cas818028 Жыл бұрын
Might be able to improve the UX with useLayoutEffect vs useEffect
@DunckingTest
@DunckingTest Жыл бұрын
I observed that while utilizing the 'next 13' version in the development environment, I encountered significant delays in page loading during navigation. The loading times between pages were quite extended, ranging from 10 to 20 seconds. Furthermore, upon initializing the initial server, the loading time for the first page was even more prolonged, spanning 40 to 50 seconds.
@laptopuser5198
@laptopuser5198 Жыл бұрын
Looking forward to the upcoming remix content. Its a great framework.
@alexanderbuk-swienty7334
@alexanderbuk-swienty7334 Жыл бұрын
I’m doing the same for the same reasons, also the caching issue from your last issue. I’ve really enjoyed working with Next but the app dir has just been too frustrating. Remix seems to have a better grasp on the server/client divide.
@EdygarOliveira
@EdygarOliveira Жыл бұрын
But the thing is that you’re hosting the state into a component that is not remounted when the route is refreshed. What you can do is actually put the same code into a sub component and put a key on the component that relates with the route, I think routes contain a key
@yuniorchavez8052
@yuniorchavez8052 Жыл бұрын
i don't know how it work under the hook, but i had a similar issue, and the revalidation only works wrapping in ...}
@ebeneze_r
@ebeneze_r Жыл бұрын
Went through your monster replies thread with lifeofcode and the key fix ... but it is indeed crazy that routing to another page and back doesn't re-execute the page ( unmount and mount)
@marcin___
@marcin___ Жыл бұрын
Looking forward to the upcoming state of JS survey and the feedback on Next 13 :D Switching to Remix also seems less favorable until v2, considering that a major change is on the horizon (regarding routing). It appears that we currently lack a stable, production-ready, and future-proof React framework. I suppose Qwik is our last hope :D
@lukemoralesTV
@lukemoralesTV Жыл бұрын
The v2 routing is already available as a opt in flag in the current version, if that’s your concern, you can already adopt the breaking changes in router on an existing/new project
@barnabasmeszaros8244
@barnabasmeszaros8244 Жыл бұрын
The Remix documentation guides every developer to adapt future changes. I am already using v2 routing and it's awesome.
@rsflipflopsn
@rsflipflopsn Жыл бұрын
Yo Cody, wanted to show some appreciation for your videos. Personally I am not a front-end nor web-developer (backend is my love ^^), nevertheless you explain useful concepts in short videos with awesome diagrams, which I really appreciate! Keep up with the good content and stay healthy! Love from germany
@WebDevCody
@WebDevCody Жыл бұрын
thanks man!
@sparx_super
@sparx_super Жыл бұрын
I like your folder icon 😁 what theme is that ?
@theasdazx
@theasdazx Жыл бұрын
Wondering the same thing @WebDevCody
@planetmall2
@planetmall2 Жыл бұрын
Really would love some videos by you on Remix.
@jesse9999999
@jesse9999999 Жыл бұрын
At this stage i am confused at why people are using app router when pages works just fine? Next have said there are not foreseeable plans to deprecate pages and its so easy to use, rsc's just feel like a huge detour for no real payoff
@ziaahmad8738
@ziaahmad8738 Жыл бұрын
i ran into the same issue and nothing really worked for me, ended up moving data fetching to client side.
@JohnSmith-gu9gl
@JohnSmith-gu9gl Жыл бұрын
you will love remix. No REST, GraphQL or tRPC is needed. SSR and rehydration out of the box and you can use your models directly. Less overhead and fast DX!
@alexanderpedenko6669
@alexanderpedenko6669 Жыл бұрын
Can somebody explain, why we need at all this feature like optimistic update? It's sounds strange delete item from UI even if we didn't get response. Or I missunderstood something?
@WebDevCody
@WebDevCody Жыл бұрын
optimistic updates allow your UI to update instantly when you interact with it (and we assume the backend api request will be successful). If for whatever reason the backend request fails, we just revert the state change back to the original state and maybe show a toast notification saying something went wrong. If you don't do optimistic updates, a user with a lot of latency may have to wait 1 full second before they see their item get removed, and that's bad UX
@amixengineer
@amixengineer Жыл бұрын
did you try prefetch on client side navigation ? client side caching has become a real pain in next JS,
@arefeghbali3914
@arefeghbali3914 Жыл бұрын
I literally had this issue in NextJs 14 as well, and I was like I'm done with this, I have to use nextjs for my job but on my personal projects I use anything but nextjs. I feel like these days people don't use nextjs because it's good they use it because they have to, just because of nextjs's community and toolkit
@Rensoku611
@Rensoku611 Жыл бұрын
Would you rather use Remix over the pages router of Next?
@WebDevCody
@WebDevCody Жыл бұрын
I personally would stick to t3 stack with pages directory if the app router wasn't deemed "the future" of next. At this point, using pages router seems like holding on to a legacy approach (which the CTO of Vercel has actually referred to as legacy). This direction is making want to leave next for my side projects, and honestly this react cargo cult is making me want to leave react.
@real23lions
@real23lions Жыл бұрын
@@WebDevCody hope you keep continuing to show the new stacks you use too
@gadgetboyplaysmc
@gadgetboyplaysmc Жыл бұрын
@@WebDevCodySame here man. I'm thinking of going for SvelteKit now. Rich Harris is awesome
@codefork94
@codefork94 Жыл бұрын
Have you tried sveltekit?
@thegrumpydeveloper
@thegrumpydeveloper Жыл бұрын
Eventually consistent and refetch immediately will not be solved easily by most frameworks. Either need to await the actual completion within the post (resolve a real promise), refetch later, or more complicated wait for a websocket notification. Also need something like react query’s refetch on focus to help this. I’d go with await the response and optimistic update the data rather than refetch immediately. The settimeout that doesn’t resolve as a promise is going to be a problem. This is all trying to get around a non transactional or slow db which I would solve first. If there’s a long chain of events before the transaction is complete a pending state should be stored somewher.
@g.c955
@g.c955 Жыл бұрын
what's in the network tab when you go back to Other? Does it send back the right data? I am thinking it's probably sending the previous value because that's in the cache and it'll refresh behind the scene.
@WebDevCody
@WebDevCody Жыл бұрын
I've added console logs and debuggers, the RSC does re-run and I see the new data getting printed. The prop in the client component gets old data.
@mrasoahaingo
@mrasoahaingo Жыл бұрын
It's because your component has already been mounted with the "default value", so you have to unmount/mount the same component... or use something like useQuery?
@WebDevCody
@WebDevCody Жыл бұрын
Yeah that’s probably the issue, although even navigating away from the page seems to not unmount it 🤷‍♂️
@aytee5862
@aytee5862 Жыл бұрын
I'm the same boat as you lately. All these new updates with NextJS and I feel like I'm battling unnecessary stuff constantly. Some of the changes they've made just absolutely make no sense to me. For example the new metatag system. To get dynamic metadata you have to use a generateMetadata function. Lets say you have an employee page, and you want to use his picture, name and about in the metadata. Well, with the new system, you have to make the db call twice, because there's no way to pass metadata from the Page component to the metadata object anymore for some reason??? Like I can literally see no gains for the new system over the old system they had...
@WebDevCody
@WebDevCody Жыл бұрын
I’m not familiar with that issue, but I think they have a cache function that allows you to cache things on a request level so that you’d only make one request. I just don’t think anything is explained well, or is all experimental. Look up unstable_cache 😂
@IkraamDev
@IkraamDev Жыл бұрын
I like your videos because they are more like video diaries entries rather than typical scripted KZbin videos.
@gkingpingg1453
@gkingpingg1453 Жыл бұрын
have you tried something like "export const revalidate = 0;" outside of your funcitonal component? idk maybe it helps
@WebDevCody
@WebDevCody Жыл бұрын
Yes, that won’t fix it
@gkingpingg1453
@gkingpingg1453 Жыл бұрын
@@WebDevCody Did you find any solution other than that router.refresh()?
@WebDevCody
@WebDevCody Жыл бұрын
@@gkingpingg1453 “solution” in pinned comment
@omomer3506
@omomer3506 Жыл бұрын
Hey cody, its good to show all the real life problems thet devs run into, i know you do primarily react but can't wait for a svelte video at any time
@real-oppenheimer
@real-oppenheimer Жыл бұрын
How does your "getNames" function look like? I had a similar issue when I tried a local mock API (where the "DB" is a local const), as somehow the variable/module was cached (but not the data). When I switched from a local const to something outside of the module scope (like a database (SQLite) or an actual API), it started working.
@WebDevCody
@WebDevCody Жыл бұрын
getNames reads from a .json file using `fs`; it's an external data store
@nirjoyhasanantor3149
@nirjoyhasanantor3149 Жыл бұрын
I think we need to shift to "a" tag from "Link" tag
@doreto95
@doreto95 Жыл бұрын
… or don’t use app routes and use good old relatable pages route
@nirjoyhasanantor3149
@nirjoyhasanantor3149 Жыл бұрын
yeah but i think using "a" tag is much better if we are used to with app router@@doreto95
@ian5004
@ian5004 Жыл бұрын
I think this can be fixed by wrapping the getNames function in unstable_cache and assigning a cache tag and then calling revalidateTag instead of revalidatePath when removing the name. I also could be completely wrong and unstable_cache is still no where near production ready but at least the team at next is trying to figure out a method to properly cache server actions.
@zhanezar
@zhanezar Жыл бұрын
please give svelte and svelte kit a try i think you will like it
@adimardev1550
@adimardev1550 Жыл бұрын
no, that's actually how next js work ever since 12. but any how, you still gonna have to deal with it manually which is a bit of a pain when you're working with big projects. react-query used make this easy, but recently next-14 just break up any entire ecosystem of libraries and stuff. you'll gonna have to rethink everything not just the mental model. which is painful by the way.
@mikedev4673
@mikedev4673 Жыл бұрын
Have you tried using next’s fetch api? Just wondering because I just started messing with the framework myself and I used the fetch with “no cache” option and It works ok for my use-cases 😅
@WebDevCody
@WebDevCody Жыл бұрын
I don't really interactive with third party apis for my side projects (I connect to the database directly to fetch my data)
@mikedev4673
@mikedev4673 Жыл бұрын
@@WebDevCody try making a route in your next api folder, use your getNames in the route and fetch it with with no cache option
@WebDevCody
@WebDevCody Жыл бұрын
@@mikedev4673 yeah that might fix it, but the purpose of RSC is I don’t need to make an api endpoint at all. If I did that I’d might as well make a separate api server using nest or go
@butwhothehellknows
@butwhothehellknows Жыл бұрын
Love you sir! Good job as usual ❤
@WebDevCody
@WebDevCody Жыл бұрын
love you babe!
@lexsemenenko
@lexsemenenko Жыл бұрын
How do I switch to Remix my three large projects in NextJs that are in production
@WebDevCody
@WebDevCody Жыл бұрын
You don’t lol.
@ntdash2153
@ntdash2153 Жыл бұрын
where can I go to inspect the source code ?
@WebDevCody
@WebDevCody Жыл бұрын
github.com/webdevcody/cloudinary-photos-app/tree/refresh-issue do not change removeName (it's there to simulate eventually consistent updates)
@ntdash2153
@ntdash2153 Жыл бұрын
@@WebDevCody ok, thanks
@TomAinsworth94
@TomAinsworth94 Жыл бұрын
Hey Cody, you’ve probably been asked this a million times so sorry if you’ve mentioned it before, but what’s the setting/extension you have to highlight nested blocks in different colours? I’ve got different brackets turned on but can’t find how to have the vertical nesting blocks different colours.
@WebDevCody
@WebDevCody Жыл бұрын
Rainbow indent
@TomAinsworth94
@TomAinsworth94 Жыл бұрын
@@WebDevCody thanks man, I actually found your vid from 11months or so ago, which went over all of your extensions (thanks a lot!) You mentioned in that vid, putting a link to it, in future vids descriptions, not sure if you ever did that or not but I couldn’t see it in this vids description.
@lifeofcode
@lifeofcode Жыл бұрын
I know this issue man, it's not really a next issue, it's fundamental of how react works. I have ran into this plenty of times you need to set a key on your Other component. When it's re-rendered it doesn't know that the prop has changed. (think about when you map through an array, how you need to set a key for react to know that item is different from the others, and know when to render it.) When Page re-renders, and diff's the vdom tree it can't tell the difference from Other component with initialNames from how it was before, and how it was after initialNames object was changed. You need to force some kind of key onto it as if you are mapping throug list, so when Page re-renders it can tell Other component as changed in the vdom diff, I feel should fix your issue.
@lifeofcode
@lifeofcode Жыл бұрын
The issue clicked for me when I seen that you had to set the userEffect to listen for the initalNames change to fix it. I feel very strongly this is a vdom diff issue when re-rendering.
@deeperlayer
@deeperlayer Жыл бұрын
no in next most issues is because fetches for server actions or apis are done incorrectly from a server component, you shouod 'use client' and revalidatepath('client side page path')
@Ghareonn
@Ghareonn Жыл бұрын
I have the same thought. He's getting initialName from props and assigning it to useState. React only evaluates useState initially it doesn't care that the props have changed
@build-things
@build-things Жыл бұрын
This sounds like it makes sence il have to give it a shot
@WebDevCody
@WebDevCody Жыл бұрын
I'm using a key on my map, so it's not that issue.
@safarl45
@safarl45 Жыл бұрын
Remix owns
@balduin_b4334
@balduin_b4334 Жыл бұрын
So I think there are 2 separate problems here: 1. The setState(initialNames) not setting properly on the redirect 2. the data from an Api not getting fetched when the req. comes but in the moment you revalidate that route I don't think there is an easy way to work around that revalidation stuff. That's why we have to do a router.refresh() but because that is a client side refersh, react doesn't remount the other component, therefore the setState hooks initial value doesn't get set because it just rerenders the component, that's why we have to use the useEffect to update the state on changing props getting passed to the child. I think that problem is solvable by giving that Component a key that is going to change when the data is fresh (e.g. the initialNames.length) so that react actually handles is as a new component and therefore the useState hooks is getting run with the new default value
@WebDevCody
@WebDevCody Жыл бұрын
That does fix it, but my ultimate question is why is there so much complexity to show fresh data? It’s my main concern with the app router
@balduin_b4334
@balduin_b4334 Жыл бұрын
@@WebDevCodysame question here, if I understanding correctly all the more annoying hacky things (like the key stuff) are results of revalidatePath() immediately revalidating and not on a request coming in, that whould only result in more loading state if you delete the cache, but why don’t the do it like tanstack query where you mark something as stale and revalidate when a request comes in and you stream the updates in. RSCs support that, in a way, not with updated data but the suspense stuff is also streamed in if I am not wrong
@brandonflorian9044
@brandonflorian9044 Жыл бұрын
Did you add "no-cache" to your fetch? I didn't see what the getNames function does
@WebDevCody
@WebDevCody Жыл бұрын
I do not use fetch anywhere in this code
@brandonflorian9044
@brandonflorian9044 Жыл бұрын
Okay my bad. For me I had this same issue with updating my user profiles. I am using fetch though and after adding "no-cache" it solved my issue and behaves as expected. @@WebDevCody
@fredheladrienkissie1404
@fredheladrienkissie1404 Жыл бұрын
Do you have a github link to your issue ? i would like to peek at it to see, because this seems to me like your component doesn't get unmounted, initialNames changes and is passed to useState, but useState do not directly updates to the props unless your component has been unmounted.
@WebDevCody
@WebDevCody Жыл бұрын
I could get something setup for you if you're interested: github.com/webdevcody/cloudinary-photos-app/tree/refresh-issue
@WebDevCody
@WebDevCody Жыл бұрын
github.com/webdevcody/cloudinary-photos-app/tree/refresh-issue
@janmarshalcoding
@janmarshalcoding Жыл бұрын
Well, I guess it's time to start learning PHP 😂✌🏻
@emrerdem1
@emrerdem1 Жыл бұрын
I would love to see Remix content!
@RolandAyala
@RolandAyala Жыл бұрын
NextJS 13 is such a mess. I feel like I should be using NextJS because ecosystem matters, but every time I (re)start down the path of using NextJS, I remember what drove me to Remix, which has been a wonderful experience. Nextjs caching is a constant source of friction for me, and even invoking simple actions is far more complex than is needs to be. I do wish Remix had Authjs support (Remix-Auth is works fine, but would feel better using Next-Auth for being battle tested), and Next has better HMR, and better community support delivering things like bundle analyzers, but overall, I find NextJS to be half-baked and overly complex.
@OcielGonzalez_mx
@OcielGonzalez_mx Жыл бұрын
Does anybody knows if nuxt suffer the same thing?
@WebDevCody
@WebDevCody Жыл бұрын
I doubt it, everything the vue team touches is often gold
@yourockst0ne
@yourockst0ne Жыл бұрын
​@@WebDevCodyso I wonder why you're not choosing Vue over react then?
@yousafwazir3167
@yousafwazir3167 Жыл бұрын
Angular ?
@chrishabgood8900
@chrishabgood8900 Жыл бұрын
It is more of a caching issue than a db sync issue?
@WebDevCody
@WebDevCody Жыл бұрын
it's a combination of all of it imo
@phantazzor
@phantazzor Жыл бұрын
did your bug get fixed on 13.5?
@WebDevCody
@WebDevCody Жыл бұрын
I haven’t checked, I doubt it
@augustoeduardo209
@augustoeduardo209 Жыл бұрын
Its crazy how react state is still a mess. Recomend move to svelte.
@farhanhelmycode
@farhanhelmycode Жыл бұрын
Looking forward for remix content
@judegao7766
@judegao7766 Жыл бұрын
I think the router cache only caches the RSC payload, which is obtained after you call the revalidate path on /other at the end of the server action. Since your DB is not strongly consistent, the RSC payload contains the stale data, but that is what gets cached in the client only router cache. Even though you have optimistic updates on the client component, when the page is revisited, react will build the page from scratch, which is by constructing the server component from the payload cache, and render fresh client components which do not preserve the optimistic updates that you did a while ago.
@judegao7766
@judegao7766 Жыл бұрын
The solution is to let the server action tell you when the data is fully replicated across multiple replicas, and then use revalidate path.
@stln768
@stln768 Жыл бұрын
Did you stick to this?
@WebDevCody
@WebDevCody Жыл бұрын
nope
@stln768
@stln768 Жыл бұрын
@@WebDevCody too bad
@AvisekDas
@AvisekDas 8 ай бұрын
@WebDevCody React query can fix this problem. Vanilla NextJS with server actions and revalidatePath is not always the complete solution.
@universe_decoded797
@universe_decoded797 Жыл бұрын
Oh boy, glad I’ve switched to Nuxt. No more pain
@therealdevopsintern
@therealdevopsintern Жыл бұрын
@web dev Cody, the problem is not nextjs, instead the problem is with nextjs App router. I have been using the pages directory and I have not come across any of this.
@WebDevCody
@WebDevCody Жыл бұрын
yes, but since app router is part of next js, and the community is obviously switching to app router and the CTO has called the pages router "legacy", we might as well just say next.
@luiswebdev8292
@luiswebdev8292 Жыл бұрын
I'll keep using Pages router
@oscarljimenez5717
@oscarljimenez5717 Жыл бұрын
This kind of errors will happen only if you do something like this names.json mutate, i thing Nextjs is caching that and then don't know how to remove the cache or something. Is hard to identify the error, clearly something that Nextjs is doing wrong. But i been using Nextjs 13 app router + tRPC and is kinda good, tRPC have now a new package for the app router, is very smooth the DX, also you can handle mutation in the client if you need, and avoid Server Actions. I tried to reproduce your problem, actually the problem is the revalidatePath that is not forcing a client cache, is weird, few days ago was doing it right, maybe some version update. Also if you're tired of Nextjs and React, you can look others frameworks, nothing is stopping you.
@WebDevCody
@WebDevCody Жыл бұрын
The names.json isn't really related. I ran into this same issue using a third part api which was eventually consistent. I decided to recreate the same issue with a timeout and fs.writeFileSync to make testing easier. I know nothing is stopping me from using something else, but I REALLY WANT next and the app router to be good, but it's not there yet imo. I'm going to play around with Remix for a while. I've been trying to give the app router a solid try for a couple of weeks, but I'm just not convinced it's worth using yet.
@oscarljimenez5717
@oscarljimenez5717 Жыл бұрын
@@WebDevCody Hi, i been testing with your code a little bit, and i notice it a problem. Your removeName function is wrong. Your function is like this: export async function removeName(name: string) { setTimeout(() => { let names = JSON.parse(fs.readFileSync("names.json", "utf-8")); names = names.filter((n: string) => n !== name); fs.writeFileSync("names.json", JSON.stringify(names), "utf-8"); }, 1000); } but it should be like this: export async function removeName(name: string) { return new Promise((resolve) => { setTimeout(() => { let names = JSON.parse(fs.readFileSync("names.json", "utf-8")); names = names.filter((n: string) => n !== name); fs.writeFileSync("names.json", JSON.stringify(names), "utf-8"); resolve(names); }, 1000); }); } the moment i update it like this, everything work like charm. Even without useOptimistic, i test it with only useState and it WORK, useOptimistic is better for data with Suspense. So the problem you're having is that removeName function is being fire after the revalidatePath, because await is not waiting nothing. Give it a try and tell me if it work.
@WebDevCody
@WebDevCody Жыл бұрын
@@oscarljimenez5717 that function was setup in a specific way to simulate an eventually consistent update. As mentioned in the video, these type of databases take time to actually write the data and have it propagate throughout the system, this is why I have the timeout WITHOUT the promise, otherwise you’re just pretending your writing to a consistent database. If you change that function it’s like you’re just writing to sql which defeats the purpose I’m trying to highlight
@gustavstreicher4867
@gustavstreicher4867 4 ай бұрын
I suspect that you should be able to just remove the state in the 'Other' component and the 'useEffect' that calls its 'setState' along with it. React components will re-render if their props change. So, I suspect that the component is in fact re-rendering, but then you're rendering 'names', not 'initialNames'. In your code, 'initialNames' is just used to initialize the 'names' state, which only happens when this 'useState' was called for the very first time, leaving 'names' stale in comparison. If so, then this has nothing to do with NextJS and everything to do with plain React.
@shreypansuria3335
@shreypansuria3335 Жыл бұрын
5:34 you have to keep router refresh here because you commented revalidate path from your code. If you keep it, i think you dont need it router refresh. P.S. This is not tested from my end, it's just a logical statement.
@WebDevCody
@WebDevCody Жыл бұрын
there are other issues that occur when you add it back to the server action with the UI deleting the entry and then it adds the old list back
@niZmosis
@niZmosis Жыл бұрын
Still have an issue if the update fails, you'll need to revert the optimistic update.
@deeperlayer
@deeperlayer Жыл бұрын
Dude that is an issue with use client vs use server... your route other is a server component that means the fetch request originates on the server not from your browser that is why revalidatepath doenst work you should 'use client' on the page that need to fetch the data not the component. that not a next issue but rather a misconception for when to use SC vs CC
@build-things
@build-things Жыл бұрын
I feel like that's not a good solution they have made server components that way to make it easier to do secure api calls and to clean up the files. Iv used the solution you are talking about but it gets messy. I end up having a use client page that calls a route Handler to do secure requests
@deeperlayer
@deeperlayer Жыл бұрын
@@build-things that is not correct at all am not gunna argue with you and give you reasons ..just so to the utube website open the network tab and see for yourself when your press like the fetch request to the api originates from the client...do u think youtube are wrong and messy too ?
@WebDevCody
@WebDevCody Жыл бұрын
both /gg and /other are RSC. The other route uses a client component for doing the optimistic updates. Revalidate path causes your frontend to rerun the RSC which re-runs the getNames call and passes it as a props to the client component. The client component should rerender because it was passed new props, but because I pass those props into useState (because I want to optimistically delete things), the client component never shows the updated view unless I add a useEffect and I need a refresh() called from the client component because the eventually consistent endpoint means that if I call revalidatePath in the server action, it'll cause the page to re-render too soon and fetch stale data. Please with it for yourself on this branch: github.com/webdevcody/cloudinary-photos-app/tree/refresh-issue
@deeperlayer
@deeperlayer Жыл бұрын
@@WebDevCody I kept all your code the same although I would do it differently, just wanted to fix it to show you that revalidatepath works comment it out to see the difference when you go back and forth with links, also I used the optimistic cause why not :) copy the code to your project and check it out (this is a pastebin id couldn't post a link got deleted) geSwcyBU
@WebDevCody
@WebDevCody Жыл бұрын
@@deeperlayer I'm not sure I follow. I grabbed your code and added it, and I added back revalidate path. The moment you click on the X, it removes the item but then it adds it back in. So I'm not sure how you say this is working for you because it isn't for me.
@mskzzz
@mskzzz Жыл бұрын
That is why I absolutely hate refetching data after a mutation. Apollo GraphQL has it on point, just send back the whole object with an ID and it will automatically update the cache. Otherwise, you can manually update the cache based on previous value and response of the mutation. Next, please do something with the server action's return value, give us a way to tell you how to update the cache based on the action's response.
@Beyram1501
@Beyram1501 Жыл бұрын
You don't even understand how much I hate this issue, I cannot use nextjs in a working environment at the current state 😢
@WebDevCody
@WebDevCody Жыл бұрын
oh, I understand it; it's why I'm switching to remix for a bit 🤣 the pages router is still fine IMO
@ChristianNaths
@ChristianNaths Жыл бұрын
This issue has nothing to do with Next...
@WebDevCody
@WebDevCody Жыл бұрын
@@ChristianNaths how so? If I could disable client caching (which is related to next) this issue would be gone
@Beyram1501
@Beyram1501 Жыл бұрын
@@WebDevCody can't wait for you to bring some videos about it, remix is amazing I've tried it before but the community is small
@ChristianNaths
@ChristianNaths Жыл бұрын
@@WebDevCody Here's what stood out for me in the video: you call out the issue at 4:37, saying "The prop is getting the latest data, but for some reason React is just not re-rendering it". If that is indeed the case (I can't verify myself so I'm gonna take your word for it), then the issue is that you're using that prop as the _initial state_ argument to your useState invocation on line 14. React will hold onto that value on purpose-the state you use to eventually render your UI, "names", will not receive the update you're expecting it to receive; it's not supposed to. That's why the useEffect workaround works, because you're forcing that new value into that state. My guess is that if you used that initialNames prop directly, your UI would update as you would expect. Great. Now all you have to do is figure out a different way to do the optimistic update to improve your UX, because the method you chose here has this inherent bug. Here's where @danihv's suggestion (in another comment) of tracking and filtering by a blacklist of unique identifiers would work great. Send a link to a repo and I'd be happy to send a PR with the changes. I try not to be too confident when I can't actually test out a solution, but from what I saw I'm pretty sure that's all you need :)
@djoscarmix
@djoscarmix Жыл бұрын
I think in the other page server component you add export const revalidate =0 It revalidate the component and use no cache
@mistersunday_
@mistersunday_ 8 ай бұрын
REMIX REMIX REMIX!!
@philheathslegalteam
@philheathslegalteam Жыл бұрын
You’re sort of doing it wrong with the useState hook, but the non update on page navigate is a problem. I’ve had an issue for this open since first release of revalidatePath and it’s not fixed yet if I’m not mistaken. I’ve moved on from Next anyway. For sites it’s overkill, for apps you barely even need SSR anyway. Having to wait 2 full seconds for a goddamn hot reload to run is ridiculous. That combined with this fiasco of an app dir release makes it easier to just stop usage. Hey devs if you want peace of mind look at this and decide for yourself: SPA: Vite + Generouted SSG: Astro SSR: Remix Hybrid (mostly static, but some ssr): Astro Hate JavaScript?: Astro + HTMX
@Abdul_Suleiman
@Abdul_Suleiman Жыл бұрын
Add this to the other page export const dynamic = "force-dynamic"; export const fetchCache = "force-no-store";
@WebDevCody
@WebDevCody Жыл бұрын
won't fix it
@alecstrickland7182
@alecstrickland7182 Жыл бұрын
React's state management was designed by a 500 year old gold fish. Using a good state management library like MobX instead makes React so much better.
@JEsterCW
@JEsterCW Жыл бұрын
Zustand*
@FedericoGobea
@FedericoGobea Жыл бұрын
This has nothing to do with Nextjs, this is pure react issue. useState will only populate the initial props on the first render.
@WebDevCody
@WebDevCody Жыл бұрын
Yes but when I redirect between pages, wouldn’t you expected the useState to be cleared because it was a new navigation?
@Balance-8
@Balance-8 Жыл бұрын
Ive had this same issue
@ajinkyax
@ajinkyax 8 ай бұрын
You should do colab with sammeechward
@MikeNugget
@MikeNugget Жыл бұрын
The true reason to use overwhelming React virtual DOM is to flex other frontend devs showing they know little while architecting the whole caching system with the help of AI 😂
@WebDevCody
@WebDevCody Жыл бұрын
react is both dogma and cargo cult
@alexjohnson-bassworship3150
@alexjohnson-bassworship3150 Жыл бұрын
Once you Remix, you won't go back!
@lewyathan
@lewyathan Жыл бұрын
@joshtriedcoding where you at? we need you to rip off this video and make it your own ;)
@truth-12345.
@truth-12345. Жыл бұрын
Thankfully I chose Remix.
@brokula1312
@brokula1312 Жыл бұрын
But why are people so hard wired to React. It's literally the worst renderer out there. We use Vue3/Nuxt3 and never had any issues. No performance tweaking, programming model is very consistent, easy to use and understand. So is Svelte and many others.
@bbfrancis23
@bbfrancis23 Жыл бұрын
Instead of read have the write return the record.
@WebDevCody
@WebDevCody Жыл бұрын
the write is deleting the item from the database, so I'm not sure why returning the item I delete from the action helps in this scenario.
@bbfrancis23
@bbfrancis23 Жыл бұрын
Return the new array or manually delete if api is successf.
@spencer5051
@spencer5051 Жыл бұрын
You only know the id of the item to delete, not the query the client is using especially if you're using pages, skips etc.@@bbfrancis23
@airixxxx
@airixxxx Жыл бұрын
5:03 that has nothing to do with Next, a useState variable is never going to update based on initial props, that's React 101. You need to use the prop directly not assign it to a useState and expect it to change. If you need to assign it and want it to change you can change the key prop of the component, basically anything is better than placing a random useEffect.
@dragosnc6604
@dragosnc6604 Жыл бұрын
Have you at least tried it? It will still not work, It's a next thing, very annoying
@WebDevCody
@WebDevCody Жыл бұрын
it has everything to do with next. I setup the exact same layout using a SPA using react-router-dom, the page reloads with fresh data when lifting initialNames to the parent component and passing it down as props. The issue is Next is sending a cached version of the props when the page loads, which means the data I just fetched from the server is NOT passed to the component for it's initial render. It's not until the router.refresh() is invoked that it tries to pass the real value of props into my client component, but at that point it's too late because it's been cached in the useState(), which is why I also needed a useEffect. If next did absolutely no caching, this wouldn't appear.
@airixxxx
@airixxxx Жыл бұрын
@@dragosnc6604 It won't work even if Next would fix their problem, a nested component won't update a state variable initialized with props the component received if those were to change. The only way to do that is to change the key, or God forbids put initialProps in the dependencies of a useEffect hook like this guy did.
@eshw23
@eshw23 Жыл бұрын
If your to dumb for Next im to dumb for Html
@amershboul9107
@amershboul9107 Жыл бұрын
use the tag in the navigation, this will hard reloaded your route :)
@WebDevCody
@WebDevCody Жыл бұрын
might as well use php at that point
@amershboul9107
@amershboul9107 Жыл бұрын
@@WebDevCody 😂😂
@lukmanmutoif8070
@lukmanmutoif8070 Жыл бұрын
😂😂😂
@feralaca123
@feralaca123 Жыл бұрын
Not only next, but also react is boring me this days.
@harunalrd
@harunalrd Жыл бұрын
The most problematic framework 2023
I might be enjoying Remix more than Next
11:02
Web Dev Cody
Рет қаралды 42 М.
I'm Ditching Try/Catch for Good!
10:29
Web Dev Simplified
Рет қаралды 197 М.
人是不能做到吗?#火影忍者 #家人  #佐助
00:20
火影忍者一家
Рет қаралды 20 МЛН
Мясо вегана? 🧐 @Whatthefshow
01:01
История одного вокалиста
Рет қаралды 7 МЛН
Fetching Data Doesn't Get Better Than This
6:58
Josh tried coding
Рет қаралды 146 М.
Breaking Up with Next.js 💔
20:48
Piyush Garg
Рет қаралды 63 М.
Remix is starting to excite me
6:43
Theo - t3․gg
Рет қаралды 41 М.
Why did OpenAI move from Next.js to Remix?
10:41
Wes Bos
Рет қаралды 205 М.
Is remix any good?  Let's try it out!
28:55
Web Dev Cody
Рет қаралды 15 М.
Inertia 2.0: It's like Next but better (and you can use React!)
19:02
Theo - t3․gg
Рет қаралды 62 М.
Remix is a NEW JavaScript framework you MUST try
9:10
Fireship
Рет қаралды 531 М.
AI Is Making You An Illiterate Programmer
27:22
ThePrimeTime
Рет қаралды 113 М.
Why Signals Are Better Than React Hooks
16:30
Web Dev Simplified
Рет қаралды 498 М.
How Remix solved React’s client state management problem
6:08
Thomas Gauvin
Рет қаралды 35 М.