6 ms·
Widget Driven Development
- alextheparrot 5y agoWould this work with server side rendered applications? We SSR a lot of the data calls, as the identifiers to be fetched is usually available in the URL. —— Nvm, I see that’s listed as a React Query feature.
- hitekker 5y ago> [Widget Driven Development] makes the data flows transparent, architecture flexible, the code resilient and easy to test. A direct quote from my "expert-junior-evangelical" phase. When I marveled at my own cleverness & marketed my brand-new paradigms to my unfortunate peers. Lots of assertions, few citations, no research. All the fun was in coding, not in studying books or even the industry at large. Then, business requirements changed and I was left to maintain over-engineered monolith of my own making. After a few cycles of hubris, I learned the danger of selling fads as evolutions. It hollows you out.
- discreteevent 5y ago> not in studying books or even the industry at large In fairness the author spends most of the article explaining the approach of the industry at large (it's a good explanation too).
- hitekker 5y agoIt appears like a good explanation. But other commenters have pointed out how it lacks precision. Name dropping CSS modules, React query and other technologies is marketing, not research. By comparison, this article properly analyzes an actual industry trend, not generalizing one developers experience: https://martinfowler.com/articles/micro-frontends.html https://martinfowler.com/articles/micro-frontends.html I’m not a believer in micro-frontends but the quality and intent Marin fowler’s of writing is actually respectable.
- alexey2020 5y ago>the quality and intent Marin fowler’s of writing is actually respectable. Sorry, didn't want to be picky, but the article you mentioned is not written by MarTin Fowler. And I also didn't find there many "citations" you were looking for in my article. I'm sorry that you found my article of a little quality. I did my best trying to analyze different approaches to Data Management, How we came to those and their problems. I illustrated those with the my own diagrams to help readers better understand the concepts. The article is based on my 10+ years experience in the industry. It went through many iterations of reviews and corrections. There nothing unique in the approach I described. It builds on what libraries like ReactQuery allows to do. I basically just tried to formalise why I see this approach as the next logical step in how we approach building UI apps. I'm not a native English speaker and not a professional blogger. Most probably there are ways to write such an article better. I do my best learning how write better. Having said that, I think you are not fair comparing it with your "expert-junior-evangelical" phase.
- pjmlp 5y agoAnd yet another round on the Web GUI carrousel. https://en.wikipedia.org/wiki/List_of_widget_toolkits https://en.wikipedia.org/wiki/List_of_widget_toolkits
- tmikaeld 5y agoThe benefits seem unclear to me, especially how this solves the shared-state issue. Is it just that each "widget" calls the same API "manager" and propagates the changes to every widget in the event of a change? Isn't this exactly what Redux already do if you use actions to fetch data and put it into the store, with the difference that each "widget" manage filters and state based on the fetched API data? Seems like it could create a lot more code with less re-usage, since every widget has to manage this themselves.
- alexey2020 5y agoWith pure Redux approach the mutation flow is more complex: - send mutation request to Backend - fetch updated data - put the updated data in the Store - see the updated data propagated in components The suggested approach: - send mutation request to Backend - see the updated data being fetched and displayed by components To me the second is much cleaner and easier to reason about
- alexey2020 5y ago>Seems like it could create a lot more code with less re-usage, since every widget has to manage this themselves. It might create a bit more code in components, agree. I think this is a fair price for the all benefits it brings. That said, the total amount of code might be even less (no action-creators, reducers, etc.). Also declarative nature of the libraries makes the added code very easy to follow.
- candiodari 5y agoThe key thing to realise with widgets is that while the widget code is indeed complex, it’s reusable and generally you’re not writing it.
- ptx 5y agoWouldn't the lack of a shared store on the client lead to an inconsistent application state when different components fetch different versions of the data? I.e. one part of the UI could think you're logged in as admin while another thinks you're a guest user.
- cjfd 5y agoOne problem is the idea that there is a one-size-fits-all solution. An application should be structured in such a way that it fits the problem that you are trying to solve as ergonomically as possible. 'Widget Driven Development' might be very good in some circumstances but not in others.
- alexey2020 5y agoAgree. There are applications where widgets approach would not bring much benefits. Let say, applications with lots of UI state (state that doesn't exist on Server). Also not sure how it would work with realtime apps. It's the same with every approach, the are always exceptions from the rule. That said, I see the benefit of this approach for the majority of UI apps, which heavily rely on Server data.
- d--b 5y agoThis is rather vague. Let's take a more concrete example: Let's say you want to add a button somewhere that hides/shows another widget. Surely you don't want to go to the backend to do that? So how do you do it? With the store approach, clicking the button creates an action, that modifies the store (changing a visibility parameter somewhere) and repaints the UI. In the diagram there is no flow back from the "API" box to the widgets. Though it still something that needs to happen. The "API" necessarily contains some state, at least to track which component needs which data.
- alexey2020 5y ago>Let's say you want to add a button somewhere that hides/shows another widget. That's a good case. This is purely UI state, right? (we don't store it on the server). For UI state we still need to depend on prop-drilling or State Management solutions. In the article I'm mainly talking about the Data which exist on Backend (as you can also see from all the pictures). In my experience such Server data is 90-95% of all data in most UI applications and that data contributes the most to the complexity. Pure UI state is often just a fraction of the the whole State and is's often synchronous, so managing it should not be complex. So this kind of coupling will still exist. To clarify, I do not say Widgets should be 100% independent. We do not achieve complete decoupling. But moving Server Data under control of Widgets gives us closer to this.
- d--b 5y agoWell, you're comparing things that are not quite comparable then... The store approach is all about how the app handles local UI changes. Whether the action goes and fetches data from the server doesn't matter. What matters is that the store gives you a single source of truth that represents the state of the UI, and that this state gets one-way-synced with its actual dom representation.
- alexey2020 5y ago>Whether the action goes and fetches data from the server doesn't matter I tried to explain in the article why it matters. If you are comfortable with putting all the data in a single Store and this works fine to you, then you may disregard the article.
- gherkinnn 5y agoThank you for formalising this. We came to a similar conclusion as we moved from imperatively handling server state to using ReactQuery. What I got to like the most was the small cognitive load. Other than the minimally shared UI state, everything I need to hold in working memory is close by. Not that it's novel or impossible to achieve the same through other means, but that this way of building UIs often leads to a manageable result. It works very well in cases where the server is the source of truth, but I don't want it to feel like it is. The creator of ReactQuery talks extensively about the philosophy behind his library in a recent PodRocket episode. [0] 0 - https://podrocket.logrocket.com/tanstack https://podrocket.logrocket.com/tanstack
- alexey2020 5y ago"the small cognitive load" - true that! Thanks for the link to the podcast. Will definitely check this out
- filoeleven 5y agoThis article gives a great rundown of various UI layer approaches, the problems with each, and how the subsequent ones solved them. I hadn’t seen react-query or its listed alternatives before, so thanks! The one thing I’m not clear on is how this is much different from the “single global store” approach. It looks like that’s what this approach uses, and the main difference is in the “store API.” In other words, usage from components is nearly identical, and it’s the mechanics of the store itself that is changed. There’s a layer of focused queries between the store and components that hides the access (and maybe update?) mechanics from the widgets. So instead of getFromStore(“books”, bookId) // pseudocode, I am not a Redux user you instead use useBookQuery(bookId) // which includes some nice things like { isLoading, error } It doesn’t seem to resolve the need to handle the following bullet point found in the store drawbacks, it “just” pushes it into a group of queries (and presumably updates). > we now have to deal with a completely new concept, the Store, and care about a bunch of new things, such as designing and maintaining Store structure, appropriately updating data in the Store, data normalization, […] Is this separation the point? Or am I missing something else? Keeping the store access mechanics separated from the widgets that use them makes sense to me, especially when it has built-in loading/error notifications. I was going to say that “widget driven development” doesn’t really point to what this achieves by making that separation, but I may be coming around to the term with those other considerations. I suggest emphasizing the loading/error mechanics more strongly at the end of the article. React is doing a lot of work with Suspense to improve their ability to give UI feedback in those states, and it looks like this approach simplifies the data side of that.
- alexey2020 5y agoThank you for the valuable feedback! Very good question about the difference between `getFromStore` and `useBookQuery`. When using `getFromStore` you have the expectation that the value is already in the Store. Someone should have already put the value there somehow. You have also the expectation that `getFromStore` is synchronous and simply gives you nothing if the value is not there. With `useBookQuery` you expect the value to be fetched from Server. There is no 3rd party to care about putting the value in the Store. `useBookQuery` is simply like `fetch('...')` from a Component perspective. With libs like ReactQuery every component "simply" fetches what it needs, sort of directly communicating to the Backend. No intermediary party (like a Store) >React is doing a lot of work with Suspense ... Yeah, I heard about React team collaboration with libs like ReactQuery on making Suspense work with those, also on server side. But I'm not much into that Suspense topic, so decided to not mention anything about it. >I suggest emphasizing the loading/error mechanics more strongly at the end of the article. Thanks for the suggestion. I will think about it.