Why you should lift component state up to the URL
Ойын-сауық
"How can I sync component state with the URL?" This is one of the most common questions I see asked in the React community, and in this video we're going to learn why trying to synchronize state between your React app and the URL is a bad idea - and the right way to address this issue.
- 0:00 - Intro
- 2:04 - Implementing sorting in React
- 17:06 - First attempt at shareable URLs: Synchronizing React state
- 20:17 - Fundamental problem with first attempt
- 21:43 - Second attempt at shareable URLS: Hoist state out of React
- 29:13 - Outro
Links:
👉 Demo: 2022-05-16-hoisting-state-to-...
🧑💻 Source on GitHub: github.com/samselikoff/2022-0...
💅 Table component from Tailwind UI: tailwindui.com/components/app...
Пікірлер: 85
Hey all! Reposting a comment here since I'm seeing the same question: The takeaway of the video isn’t that you should do sorting/filtering/pagination all on the client side. Whether you do that depends on what you're showing, the size of the data set, and what you want the user experience to be. The point is that when you expose new URLs, that information shouldn’t be duplicated inside of React. Whether you filter/sort/paginate on the client or server, in both cases, you should not duplicate the information contained in the URL. The URL is the single source of truth. The reason I went with the refactoring I did in the video is because it’s usually what leads to the issues we discussed. Someone starts out implementing something in React state, then a new requirement comes along that says that information should live in the URL. That’s when this refactoring applies. The lesson goes beyond sorting/filtering/paginating data tables - it applies to any state that starts out in React and then moves to the URL. It could be as simple as a selectedDay or whether a modal is showing or not. A lot of this sort of state only ever lives inside of React (or Vue, etc.), but then you want to be able to share that state of the app via a URL. It's at this moment when you should lift the state out of React, into the URL, and derive everything you can in the UI from the URL. The URL has become the new single source of truth for that piece of application state.
@AndersonSousa33
2 жыл бұрын
Sam, what about refetching? Ins't the app refetching the data using this method with ?
@samselikoff
2 жыл бұрын
@@AndersonSousa33 It depends on the framework and data fetching library you’re using but typically a page will reuse its data and then refech in the background.
@tonybrown7847
2 жыл бұрын
Really good stuff here
@UmarMunir94
Жыл бұрын
then why not get rid of app state inside react/vue altogether? We can just store all the app state in urls and get rid of complex state management libraries like redux.
@hebestreitfan6973
Жыл бұрын
@@UmarMunir94 Types of state differ. Someone might want to share a link to a Facebook page, but not they message they're writing to their wife at the same time.
"We as developers don't own the url" You're absolutely right, and that phrase saved me, thank you, sir. Great video!
I can hear Adam saying, “That’s why I used anchor tags, bud.” But seriously, this has given me something to think about and a new tool in my toolbox. Your tutorials are very well done and I appreciate your attention to detail.
Interesting! This is actually what I did intuitively when I built a filtering system for a website of mine 😊
I would love to see this extended to take into account larger sets of data and how we can implement/handle pagination
@ivodelev9794
2 жыл бұрын
I've just finished my table component, but ended up doing my sorting on the client side, because it's part of a form and i need to save the state when sorting. Ended up creating both th and td components and mapping through them for desc/asc added desc: boolean key/value to the object. Result is pretty good.
Great one! Also it nice to see a fit developer.
Excellent! Not only does it make client-side state management easier, it pushes you toward creating an app with more finely grained shareable links for better UX
This is really impressive. What a great tutorial!
This is SO powerful -- thank you for the insight and wisdom, Sam :)
Really like your videos mate! Insightful and so easy to follow... please do keep posting more Remix related stuff!
Your descriptions are really really really good. Always watch to the last word of your video
Nicely put. I new everything explained here but watching you explaining is a joy
As always, exceptionally good video. Thank you, definitely going to take the learning from here to the app I am working on, where I have exactly that problem - synchronizing state with the URL.
Hey Sam, Thanks for this awesome video. Hope you are doing well.
If you can reduce screen resolution while recording or use a larger font size it will be great.
From the framer motion to this lifting state to the URL, I learn so much from your video. crazy. thank you
This was an amazing video with a very detailed steps on how to approach this feature in an app. Thank you so much for making this one!
Love the video, you definitely got a new sub from me! I've been working at an e-commerce company for the past few years, and this pattern definitely simplifies a lot of the work we do day to day :)
good and smooth explianation as always.
I've always wondered what the best practice is around synchronising the URL - thank you for the example!
These types of videos are amazing. Demonstrating how to solve real world problems
super clean as always
Seriously great stuff. Thanks!
It was well spent 30 minutes! The way you explained all implementing details and the reasoning behind it was great and surprisingly easy because how you approached the problem and went through it step and step.
Simple but really cool solution ! I love it
I’ve been searching for a solution to synchronize my app state with the url, previously used a lot of effort managing it from react. Thanks a lot!
I'm gonna take inspiration from this for a new project I'm working on, this is such a cool pattern to follow
Sam, This is so amazing stuff, I learned a ton in this video thank you so much, I would love to see more content about remix 📀, thanks again
That was really helpful, thanks!
Excellent video. Thank you.
Thanks. It was really helpful.
Another amazing video! I know this video is not Remix specific, since the idea is more general, but it would be really dope if you do more videos on Remix. I’ve been doing Remix for the past couple of days and (imho) it’s an absolute game changer. The concepts, the philosophy and the APIs! Anyway, you’re doing amazing work, Sam! Keep it up!
This is nice! Thank you for this.
another great video!!
thank you so much, you just opened a new way of thinking for me
6:42 - I zoned out and this cracked me up way too hard lol
Wow great video!
This is really helpful, thanks alot !
I love discovering things im gonna need in future
SAM you helped me aloooooooooooot. thank you
This is a fantastic video and it really shows the strengths of Remix. Once he hits that point of "well now we have to synchronize state..." he stops and says "what if we just remove all the onClick javascript and just use ?" And he didn't even cover the progressive enhancement part of Remix, where even if the javascript doesn't load, the sorting could _still_ work because it’s just HTML & URLs.
@b99andla
2 жыл бұрын
But there is nothing specific to Remix about this reasoning? It can be done just as well in "ordinary" React, as well as in Vue or Angular?
@jimnielsen584
2 жыл бұрын
@@b99andla This couldn't be done _solely_ in client-side React. For example, If you had a purely client-side react app and you pass URL search params like `?sort=email` and the javascript doesn't run for any reason, your page will be blank. But with Remix, it would render as normal.
@Quenjii
2 жыл бұрын
@@jimnielsen584 react-router is all you need to acomplish this.
Great video
Elegant and brilliant
Awesome video! Do you have an implementation like this for a search textbox with auto complete for the table? Keep up the good work!
Some neat state mgmt 👌
I want MORE!
nice wish i saw this earlier I was struggling with this for awhile took way too much time refactoring, when i should have used the url for state-management from the get go
thanks ❤
Hello Sam, Big fan of your work ❤. Just wanted to how you use vim so effectively. I am also using vim for almost 1.5 years now. But I am not as fast as you are. Please can you make a video on that if possible. It would really help a lot.
Great video! Only thing might change would be separating sort & desc in the search params, then the escaping wouldn’t be necessary and the url much cleaner 🥰
Great tutorial, may I know which software did you use to record the video?
Hi Sam I have a quick question regarding this. Thank you for the awesome and helpful video by the way, it was very clear. Do you still recommend this approach with some of the following (and more complex) requirements? - some filters don't have a 1-1 match between the query parameter value and the label, so that would either need to be matched in the client or fetched from the database. For example movie cast member IDs where you then need to grab their name and picture from the database (/?movie_cast=1298,150,22816). This one gets tricky because the user can choose from the list of cast members showing their name, but then the url needs to display the linked slug or id, so then if we are only using URL state then we are duplicating the retrieval of the needed linked information. (for purposes of sharing the URL and the UI filters need to reflect the proper cast names from the provided id/slug). - filters where the value isn't a simple string, but instead needs more steps to parse and decide how to use the data. For example this filter uses different symbols to distinguish between a key having ANY or ALL values (/?genre=14,18 versus /?genre=14+18)
I usually use Next and this is the way of thinking I try to adopt for read mode pages, like search page, with filters and sort. All forms are not equals in web. Forms for updating things need to be build in a different way that forms for reading things.
awesome
God im learning so much rn
Great video, one question though because you are using a link for the filter at every change there will be a history push and if for example the user sort 5 times if it clicks back on the browser to return to the privou-se page only the filter would change, witch in most case is not the most ideal. Not sure, what do you think?
@samselikoff
2 жыл бұрын
Yep, if you didn't want to add a new entry to the history stack I believe you can use the replace prop on Links: This still keeps the source of truth in the URL but now the back button won't just update the filter because there's no new stack entry!
I think one crucial thing is missing. Usually the list you wanna sort is long and therefore paginated, this means you have to sort on the database request level. But it's pretty easy with Remix, just move your code for getting the data inside a loader function.
@samselikoff
2 жыл бұрын
Yes exactly. The takeaway of the video isn’t that you should do sorting/filtering/pagination all on the client side. The point is that when you expose new URLs, that information shouldn’t be duplicated inside of React. Whether you filter/sort/paginate on the client or server, in both cases, you should not duplicate the information contained in the URL. The URL is the single source of truth. The reason I went with the refactoring I did in the video is because it’s usually what leads to the issues we discussed. Someone starts out implementing something in React state, then a new requirement comes along that says that information should live in the URL. That’s when this refactoring applies.
Good
GEMS 💎
The question I have this, because I already used this method, is: When we use , ins't remix refetching the data?
How would you perform the same refactor in Nextjs? The Link component does not have a to prop. Do you just use the href prop instead?
@samselikoff
Жыл бұрын
Correct, href in Next Link is the same as to in Remix Link!
@Sam Selikoff please please more remix stuff!!
amazing , maybe worked with nextjs ?
How can I learn to navigate around my editor as fast as you? Is it some kind of vim thing?
The best reason why one should use uerRouter hook all the time and not put userRouter's output into another userState hook.
Why is it important to move state out of React and into the URL? I always thought it was better to keep stuff in react state as it appears neater to the end user?!
what is the color scheme on the editor?
Your vscode settings?
I see a lot of use of `let` and no use of `const` any particular reason? Most of the variables in the video have been constants
I wish you used a more realistic example, I don’t think this approach would scale with filters for examples. It’s pretty common to filter a search like when you search a job on LinkedIn, in this case you can’t work with static links because you can compose filters
@samselikoff
2 жыл бұрын
Hmm I’ve done this plenty of times, I think it works just fine - it’s how most SSR frameworks like Rails work. Could you give an example of where you think it’d break down?
Wow no more useEffects 😃