Settings

Theme

React and Redux are a joke right?

games.greggman.com

120 points by oal 8 years ago · 118 comments

Reader

bauerd 8 years ago

>In the react world though you can’t mutate your data.

Wrong, you're free to mutate your data. What's immutable is the virtual DOM fragment that a component maps the data onto. If you want to manipulate the DOM directly (and it can make sense), how about not choosing a virtual DOM/diffing library?

>If you get 3 people react will end up re-rendering 3 times because of the code above.

Yeah, because the code above is obviously not a good idea. If you receive a list of people and loop over the members, each time triggering a rerendering, it's your fault?

>So what about trees of data with redux? The docs tell you try not have nested data. Instead put things in flat arrays and use indices to reference things in other flat arrays.

I'm not sure what part of the docs this refers to, but state in Redux is literally organised in a tree and you're free to choose data structures for the nodes that make sense. I've found that deeply nested structures make it more cumbersome to write reducers for.

>Why is the UI library dictating how we store and manipulate our data!!!

It does not do this, it's a virtual DOM/diffing library (!!!).

>Maybe someone needs to start the browser over.

This is a highly incoherent rant that mixes up criticism of immutable data structures, the Flow architecture, virtual DOMs and the Redux API. The quote above doesn't surprise me in the least.

Having said all this, the approach commonly taken by React/Redux is certainly not a silver bullet for every problem domain, but then what is?

  • stickfigure 8 years ago

    I'm about 6 months into a React project (coming from Angular1) and honestly I find the OP's rant pretty coherent. React requires a preposterous amount of code to maintain state, and Redux doubles down on boilerplate.

    In Angular-land you can just mutate some JS objects and the UI magically updates. I really miss that.

    I picked React over Angular2 because the setup was simpler and I wanted to try out this new thing that everyone has been raving about. I have a lot of misgivings about the choice. There are some things I like about React, but I probably will not choose it for my next SPA. There's just too much typing.

    • gr__or 8 years ago

      Redux is not intended to be THE state management lib for every possible use case. It sure can cover pretty much every case though as people tend to notice, that requires quite some boilerplate. For typical CRUD apps that stay in sync with the backend, I'd recommend going with MobX or GraphQL (Relay or Apollo on the client side). There you can directly mutate objects just like you're used to.

      To reiterate what other people have said. This it not a problem of React, this is a problem of people blindly jumping on the Redux hype train, without doing the required reading into Redux and its use case.

    • darth_mastah 8 years ago

      No matter what framework or library you choose, if you go past the to-do list project you will encounter certain pain points. I worked with jQuery when it was the new kid on the block, with Angular since it first came out and now with React. Every one of them gives you grief now and again. However if you develop pragmatically you learn how to avoid those pain points early on in the process even if it means investing some time. It will pay off later on. And if there is absolutely no way to mitigate the pain - just move on to another library.

      It makes me sad to see people ranting about how much typing there is in Redux or Typescript or how much boilerplate and so forth. To me this behaviour screams immaturity, because I don't know how else to explain spending energy on wining instead of finding a solution. Especially, that you don't need to look far - take redux-actions for example. Nice and simple, makes all the heavy lifting for you. If that's not cool in your view how about you actually contribute and write something of your own, rather than moan?

  • BigJono 8 years ago

    > I've found that deeply nested structures make it more cumbersome to write reducers for.

    Well, that's kind of his point isn't it? It's no more difficult to update a deeply nested regular Javascript object. But it is more difficult to update a deeply nested Redux data store.

    > Having said all this, the approach commonly taken by React/Redux is certainly not a silver bullet for every problem domain, but then what is?

    I'd argue that Redux is not just "not a silver bullet", it's an arrow head shoved into the barrel of a gun. You might kill something with it, doesn't make it any good.

    I agree completely with the rest of your points though.

neya 8 years ago

I'm one of the laggards - Over the years, based on staying around tech communities (esp. HN) I've learned not to invest time / effort into the hype that surrounds a newly launched tech. I did burn my finger a couple of times, especially with MongoDB back then, so these days I'm pretty cautious.

I'm one of the very few who didn't invest in React. I waited it out and invested into Vue.JS, instead. This is no framework war, purely based on opinions.

My opinion is pretty simple and resonates with a lot of people, apparently[1]:

    ~15 years trying to make everyone separate HTML, JS & CSS. And then suddenly everything went south and we’re writing code like this: [1]
This alone makes React a joke for me, let alone the author's post. If it resonates with you, then good for you. I may not be from Facebook or Google to have the authority, but I do know what's good in the long run and what isn't. I couldn't be happier with Vue.

[1] https://twitter.com/thomasfuchs/status/810885087214637057?la...

  • borplk 8 years ago

    The whole "separate HTML, JS & CSS" idea I don't believe is something that should go unchallenged.

    It was "best practice" back in the days for years and mostly just because it was best practice, but also because at that time it made juust that much more sense where web applications were more primitive and closer to a semantic HTML "document" with some interactivity sprinkled on top (remember when AJAX was bleeding edge jaw dropping? "LOOK THE PAGE DOES NOT EVEN REFRESH!").

    It's just some theoretical ideal that never pays any dividends in the real world and is not appropriate for a sophisticated modern web application.

    The separated HTML, JS and CSS of your sophisticated datetime picker element or auto-suggest fancy textbox are of no use or importance separately. They all need each other, they are all inter-dependent and if you force that separation on some ideological idealistic principle you create the spaghetti that any commercial web developer out in the front lines is well aware of.

    You spend a good 60% of your time on "where is the HTML for this JS" ... "where is the JS for this HTML" ... "where is the CSS for this HTML".

    I'm sure a lone programmer is going to come down here and reply about their snowflake project that "was done right".

    I don't care. Frame the code and hang it on your wall.

    Out there in the real world in teams of 10+ people with varying degrees of skill and care who join and leave over multiple years you can't have a snowflake project that is perfect in every regard. So if the eco-system doesn't give you strong suspension belts things will go south.

    If you could easily and practically switch and mix and match custom HTML/JS/CSS for any given web application then that would be something.

    We would need much tighter and stricter interfaces and so on for something like that to work.

    We all know that's nowhere near the case. Any non-trivial commercial web application will inevitably have HTML/JS/CSS that are all heavily dependent on each other and as a result the separation of them doesn't provide much benefit, and creates a whole series of problems on top too.

    • davidmurdoch 8 years ago

      React+Redux is still very focused on separation of concerns, but now it's all in the JavaScript side: "where is the JS for this JS?" is the question now. Components, states, props, actions, reducers, stores, etc. React has just as many "separation of concerns" as ever.

      • borplk 8 years ago

        I don't disagree. I don't think React+Redux is perfect or fixed every possible problem.

        A lot of those things are in a way a fundamental side effect of lenient languages and dynamism.

        Having said I think it's definitely nowhere near as bad.

        I use Typescript and modern JS and types and the modules/import system does a lot to prevent those things.

        Because in general I don't have any globals lurking around so for example the styling of a component is imported at the top in the same file so it's always nearby. So the symbols and variables that you see on the screen are more obvious in terms of where they come from.

        Redux also while not perfect if you have a reasonable amount of discipline it doesn't get as bad as the old-school stuff.

  • coldtea 8 years ago

    >~15 years trying to make everyone separate HTML, JS & CSS. And then suddenly everything went south and we’re writing code like this:

    That's definitely not what's bad about React. In fact that's what great about React -- coherent widgets (components) that are defined in a single place. Not to mention that JSX in React it's all JS and properly parsed and checked -- the "HTML" there is just sugar.

    Such separation of HTML/JS/CSS was misconceived. It makes sense for web documents and simple forms, but not for web apps with rich widgets etc (which is what we're trying to do). Tons of problems stemmed from cargo cult adherence to that.

    Everybody else, including those that add JS instructions (or ad-hoc "templating language" instructions inside HTML tags) are getting it wrong.

    • threatofrain 8 years ago

      I'd argue that back then, focusing on elegant CSS was also a mistake. Outside of well-done libraries, I've never really perceived code re-use as a big force multiplier.

      Even now with React, I still don't see much code re-use outside of libraries. When you want your code to be re-used... you exercise the discipline that a library author would. You add typings, you add documentation, you add tests, you create a Github page where people can provide info. Taking someone else's code is a commitment, so you at least want the reassurance of library-quality code.

      Otherwise when you write a component, whether in the old school html/css/js split, or in React, you're unlikely to write the component in a way that optimizes for generality, and optimizing for generality, as opposed to the narrow business case in front of you, is often a lot harder.

    • ldiracdelta 8 years ago

      And it wasn't 15 years. It been more like 40 years of trying to push Model-View-Controller architecture. Widgets instead of MVC increases code mental locality - the things that closely interact in the system are close in the code. Widgets also do not create an arbitrary cutline that doesn't fit all scenarios.

  • rhinoceraptor 8 years ago

    Is it actually better to need to have three files open at a time in order to work on a UI component?

    I think React components perfectly follow the single responsibility principle. You have a single file that is responsible for one thing: mapping data to UI. Yeah, it has some crazy syntax but it's just sugar.

    I tend to use separate stylesheets, but that file lives right next to the component file.

  • yen223 8 years ago

    To paraphrase somebody, separating HTML, JS & CSS is like taking an essay and separating out the nouns, verbs and adjectives. Sure you have achieved "separation of concerns", but your codebase now no longer has any semblance of coherence.

  • TheCoreh 8 years ago

    I don't see how vue's take on this same issue is significantly or even marginally better: https://vuejs.org/v2/guide/conditional.html

    Instead of getting HTML fragments on your JS, you get JS fragments on your HTML? Whenever you need to programatically generate markup with conditionals and iteration over existing data structures, you end up having to mix a programming language with your markup. (The other option is of course to create an entire programming syntax on top of your markup language.)

    BTW, I haven't actually used vue, so this post is by no means me saying that it doesn't have its merits or it's not a good framework.

    • rhinoceraptor 8 years ago

      Having used Angular 1 quite a bit, I think the whole DSL for HTML business is not the way to go. But at least Vue had the good sense to compile them rather than evaluate them at runtime like Angular.

  • wslh 8 years ago

    I will buy the hype once I can sit and create the whole UI/UX visually dragging widgets and not creating a single line of html/javascript/css/your-favorite-tenplate-language. Except if I am doing some real new UI/UX.

  • janci 8 years ago

    I still sitck with AngularJS because of it's simplicity. You just bind your data to the template. Vue looks similar, but I learned not to start new big project with brand-new library.

  • noway421 8 years ago

    Vue components are really following the same paradigm React does: styling, view and logic are all in one place. The only thing in which react differs here is that it uses different syntax. Instead of using attributes in the template which create a new language, react went with slightly modified javascript. And in the production build, Vue compiles html to javascript functions anyway.

davidmurdoch 8 years ago

I started working on a react native+redux project myself recently (after working with react on its own for about 1 year) and have been feeling the same way. And we've just been working on auth, data persistence, and screen navigation.

My problem with it is that there is so much abstraction that almost no prior knowledge from using other frameworks or libraries is useful. It seems like everything is magic.

Here is a chain of react tech things: React->Flux->Redux->Redux-Persist->PersistGate

The latter is talked about in documentation, i.e., "do it like PersistGate does", but I can't find PersistGate anywhere.

With so many react extensions and libraries all having their own helper functions to do everything it seems like we are no longer programming, but instead, we are tasked with stringing together configuration functions after searching for hours for the currently relevant documentation.

I think react does some pretty amazing things, but the learning curve is too steep because of fragmented documentation (mostly the community created how-tos are the problem here), confusing abstractions, and poor method naming (thinking about redux's `reducer` here).

Anyway, I, and several programmers at my company, share your sentiments; you are not alone. This will probably be my last greenfield react project.

  • hungerstrike 8 years ago

    This is exactly my experience. Eventually, I skipped redux/mobx/etc altogether by creating a singleton EventEmitter which can hold application state objects, emit events when the state changes and persist it to SQLite. For data that does not need to be in memory, I just access SQLite directly (and I can still use my appState singleton to let the rest of the app know when SQLite data has changed.)

    Yesterday I spent probably 5-6 hours just trying to figure out how to navigate easily with react-navigation. There are probably over 100 questions on their issue list asking the same thing: How do you easily navigate between nested navigators? They all have the same setup: A StackNavigator that contains a TabNavigator that contains one or more StackNavigators. Nobody knows how to do it without redux and users that do use redux have other complaints. The react-navigation examples all show a `path:` property, but they don't just have a global service that you can use to navigate to all those paths. Instead (I think) you have to wrap all of your navigators and pass around the `navigation` property. When I tried following their example of passing down the navigation property, I just get errors.

    I blame the people who tried to force their stupid functional programming ideology onto the whole framework.

    • hungerstrike 8 years ago

      Just an update: I almost gave up on react-native today because the navigation story seemed so broken. I actually spent a few hours checking out Xamarin.Forms at one point. Then I took a break and I was about to play some Rocket League when I had a eureka moment - I finally understood the simplest way to make react-navigation work the way I needed it to and within an hour I had a working implementation!

      (The trick that worked for me: Don't nest navigators directly within each other, instead wrap each one in a component class, get a ref to the wrapped navigator and then use that ref to handle navigation requests from a global navigation service that other components and services can use.)

      So, my opinion of react-native has softened a bit this evening as I've gotten over my biggest hurdle yet. After trying Xamarin out and also comparing it with my previous Ionic/Cordova/PhoneGap experience...I'm glad to be back with react-native.

      Also, Expo XDE has been a pleasure to work with - discovery of that tool is the reason I decided to re-investigate RN about 2 weeks ago. The first time I tried RN was like 6 months ago and I had spent a few days the first week just trying to get the environment working properly. This time everything just worked (and on multiple operating systems!)

captainmuon 8 years ago

The article has a point. We tend to fix issues with state by avoiding mutability. That is like going to a doctor because it hurts when you laugh, and they just say "don't laugh". I wish there was a language that embraced mutability instead [1]. Mutability is how the computer works at the lowest levels, and how we tend to think about the world.

You would use plain old data objects to store everything. Then you would have first class observers, meaning you could have callbacks react to any changes to any object. But you wouldn't use that low-level functionality often. Instead you would e.g. create a listview, and just set it to observe the array. This is like "list adapters" that are in many frameworks, but built into the language.

One thing that I'd love to be able to do is to have the data as plain-old-objects, updated frequently from one thread, and the gui living on another thread that observes it occasionally in a read-only fashion (and occasionally sends mutating messages to the backend thread). You could implement that with read-write locks, but as far as I know no framework supports it directly.

Maybe this language would have a special block that takes imperative, mutating code, and lifts it to implement the command pattern [2]. You then could "undo" these blocks, coalesce them, and so on. (That doesn't work with arbitrary code, but with most code that operates on business data.)

(Here are some questions I asked on StackExchange, trying to find out if something like that already exists:)

[1]: https://softwareengineering.stackexchange.com/questions/2298... [2]: https://softwareengineering.stackexchange.com/questions/3515...

  • trgn 8 years ago

    `One thing that I'd love to be able to do is to have the data as plain-old-objects, updated frequently from one thread, and the gui living on another thread that observes it occasionally in a read-only fashion`

    Dojo-stores, observable-collections essentially, were like that. A Dojo-view was a monitor for this. A very simple, elegant model-view design.

    I agree that we should embrace mutability. The JS-code most people write now has horrible performance characteristics since we do not take advantage of the benefits of mutating objects to manage state. Instead, in JS-world, we recreate and duplicate state all the time, spamming the heap. One library doing this is not too bad, but all libraries doing this is the main cause of slow web apps.

  • jordwest 8 years ago

    > I wish there was a language that embraced mutability instead

    IMHO Rust manages to do this really well - the system of ownership and borrowing brings all the safety of immutability to mutable data. Check out the "Why Rust" video: http://intorust.com/

    It's not really viable to use in place of JS yet (only via Emscripten, which results in a huge bundle) but the future looks bright for Rust.

  • arcbyte 8 years ago

    Mutability is actually a kluge.

allover 8 years ago

Stopped reading half-way through, as lots of incorrect stuff off the bat.

> In the react world though you can’t mutate your data

Sure you can.

> If you get 3 people react will end up re-rendering 3 times because of the code above. Each call to `setState` triggers a re-render.

Nope, calls to setState are batched.

  • ryanbrunner 8 years ago

    I think sometimes you need an outsider view to call out that the emperor isn't wearing any clothes, and that's going to result in botched details. I don't think it impacts the overall point the author is trying to make.

    I teach web development at a part-time course, and we recently redesigned our curriculum to use React + Node instead of Rails with JQuery. With the new technologies, the students are profoundly less productive or effective by the end of the course - they're doing well if they have the barest skeleton of a CRUD app up, whereas the Rails apps were all fleshed out and far more engaging.

    There's something rotten with the state of development these days - we're dealing with far more complexity and being less productive for what's usually the same result.

    • vim_wannabe 8 years ago

      One problem is people reach out to client-side code earlier than they should.

      90% of websites have no need for Javascript. Of those that do 90% won't be needing any "take over the world" frameworks, just little sprinkles of Javascript or jQuery.

      Not to mention most required uses of Javascript are interaction related. At least let me read the landing page without having me enable javascript instead of greeting me with a blank page.

      • ryanbrunner 8 years ago

        I agree. I think 90% of the "problem" with React or Redux is that people espouse using "the right tool for the job", but almost never practice it when the right tool is unsexy.

    • brightball 8 years ago

      Most of the problem, IMO, is that everybody seems to think that everything needs to be a SPA.

      The reality is that 99% of web applications are "open, check, close" experiences which benefit very little, if at all, from a front-end framework of any kind.

      The remaining applications that people actually keep open for long periods of time where the DOM needs to update over long periods of time are the only places where this approach really provides a huge benefit. Things like a chat system or actual web based software that people would be expected to keep working on throughout their day. For those types of application, React is a good fit.

      The biggest issue is people jumping on this "we need a front-end framework" train when...you really don't for most things.

    • andybak 8 years ago

      I'm a Django guy and I still feel that the ascent of Django and Rails was the high-point of productivity in web development.

      I still advocate for "progressive enhancement" as a development philosophy but the javascript kids seem to have taken over the show and regard back-end code as there for nothing more than building an API.

      For the vast majority of javascript use-cases Turbolinks/PJAX gives you most of the benefit of a client-side framework (which usually boils down to faster response times by avoiding full page loads with the advantage that you get to keep most of your logic in nice server-side languages with non-pathological ecosystems.

      Also see http://intercoolerjs.org/ - which follows a similar philosophy.

      • allover 8 years ago

        > but the javascript kids

        > with non-pathological ecosystems.

        That's just like, your opinion, man.

    • mamp 8 years ago

      React + Redux has plenty of great principles behind it: functional approach to front-end dev, understanding the importance of one way data flow, components, immutable data stores etc. Also the separation of data from UI that allows rendering abstractions that result in React Native. There's a lot of material a good engineer should understand, and it's well thought out in React/Redux.

      If you are trying to put up a few web pages quickly, then the learning curve is steep and it's probably overkill.

      However, for complex single page apps with complex data that involve a team, then the payoff is huge. Especially with TypeScript (or other). The reliability, testability and extensibility of our complex applications is amazing compared to our previous attempts over the years.

    • crispyambulance 8 years ago

      It makes me wonder what it is that actually makes a framework "take off".

      Clearly it is not ease of use nor cogency of the code one needs to write, nor even how well the developer can express their intent.

      I sometimes suspect that all this churn and complexity in the latest frameworks is some kind of unintentional group-think that optimizes for job-security by making work much more difficult than it really needs to be.

    • franciscop 8 years ago

      Has the complexity mostly come from React or from Node? I'm doing a small Node library from a similar but casual teaching perspective (all those manual middleware should be there by default IMO) so I'm quite interested in leaning your Node.js pain points.

      • ryanbrunner 8 years ago

        Node (well Express) is not a problem at all, save maybe authentication and database concepts (which are a slog no matter what language you're working with for new developers). I think Express is actually more suited in some ways for complete beginners than Rails is.

    • littlecranky67 8 years ago

      Then why don't you stick with Rails and jQuery? Modern frameworks like react (or even SPA alltogether) evolved for certain types of web applications (read that again: web applications, not websites). If your web application has requirements like offline funtionality (think mobile appstore deployment), very nice UI (think animations) or responsive UI (in terms of response times to clicks, drags etc.), you would not get far with Rails, or end up with a mixed backend/frontend code soup for HTML rendering and DOM manipulation.

      Another aspect is enterprise grade websites, where jQuery just does not scale as well or will make your code end up in an unmaintainable state. "Get beginners going fast" is a nice feature, but sometimes its more favorable to have "scales for teams with >10 developers".

      If you are making a simple website, blog or whatever, please do not use SPA but stick with the server-side frameworks we had for years.

      • mgkimsal 8 years ago

        > Then why don't you stick with Rails and jQuery?

        They're teaching classes about web development and trying to react to the perceived market demands.

        You're talking here about "if you're building X or Y, use ABC", but the class doesn't make that call, and they're trying to be attractive enough to students to choose them.

        If I was a student, and was looking to "learn web development", and I search around for what I should learn to make myself attractive to employers... I'm very likely going to find unbounded recommendations for Angular, React and Node, almost without exception. Probably not even 'likely' - it really is what I see touted weekly in many groups that I'm a part of (user groups, online forums, etc).

        The current situation for new folks trying to get in feels like a big echo chamber with bad recommendations reinforcing poor choices leading to more confused (and less productive) jr devs coming in to the field.

      • ryanbrunner 8 years ago

        I agree that there's web applications that aren't going to be feasible with a server-generated HTML stack. Anyone trying to build Spotify or Google Docs without Javascript driving the show is in for a bad time. But 90% of the "applications" I use (read: not blogs but your average SaaS app) don't require that level of complexity.

  • boubiyeah 8 years ago

    They're not always batched. They're only batched within the context of an Event listener. A fairly odd distinction made necessary because React rendering was made synchronous initially but I guess it works for most apps.

    • andrewingram 8 years ago

      The fact that it's currently within the context of an event listener is probably the wrong way to think about it. The only sane and safe way to work with setState is to think of it as scheduling a change to be made at some point in the future, and that batching will occur if possible.

      It's clear from the post that the author didn't learn how setState works, he's not aware of either batching or the callback form, which neatly address most issues related to setState.

      I didn't pay much attention to the second half of the article, because I avoid heavy use of Redux anyway. Ultimately the author shouldn't have even been looking into Redux before understanding how React works, so presumably he's been misinformed somewhere along the way.

  • VeejayRampay 8 years ago

    First thing that struck me as dishonest. The Facebook put a lot of thought in making sure all updates to the DOM are as scarce and optimized as possible, so naturally it batches them.

tck30 8 years ago

tl;dr of this blog post: "Oh no, I don't understand how immutable data structures work and need to rant about why it doesn't make sense!"

I don't want to be mean about it, but there's a lot of literature on functional programming and how mutable data complicates things as your states increase. The problem isn't how React forces you to write long code to get around immutability, the problem is the fact that you're trying to force your approach.

And no, this isn't because React is heavily opinionated -- it's because React's underlying philosophy is functional programming.

  • mediumdeviation 8 years ago

    React feels like a library written for a language that's not JavaScript. JavaScript defaults to mutability by default - there are no immutable primitives that you can easily use, and even in ES6 just maintaining immutability without deep cloning everything takes a lot of effort. In that respect React is heavily opinionated.

    • tck30 8 years ago

      Yeah, I guess that was a false statement. You're right.

    • striking 8 years ago

      "there are no immutable primitives"

      Many array prototype functions work in an immutable way like map and reduce

      • mediumdeviation 8 years ago

        Updating an array element

          arr[3] = 'New content';
        
        Updating an array element immutably

          arr = arr.map((element, index) => {
            if (index === 3) return 'New content';
            return element;
          });
        
        It's possible, sure, but it feels terrible. JavaScript objects want to be mutated - it's the most idiomatic way of interacting with them. Whether functional programming paradigm is good (I certainly feel it is) is beside the point - JS wasn't designed for it.

        When I think of immutable primitives, I think of Python's tuples, which will raise a big fat error when you try to mutate them, or even better, Swift's structs, which gives you a new copy with every mutation.

        • bmpafa 8 years ago

          I know your point wasn't strictly pertaining to boilerplate, but for an apples-to-apples comparison, the most succinct way to change a member of an array immutably would be something like:

            arr = arr.map((e,i) => i === 3 ? 'new content' : e)
          
          That said, idiomatic or not, functional patterns in JS are a boon for debugging (especially with Redux devtools & time travel). To your example, even if mutability is more succinct, using map() lets me chain all sorts of methods together without storing intermediate values in vars.

          Between the spread operator (...), immutable array methods (slice, reduce, map, filter, and even sort if preceded by .slice()), immutability in native JS ain't half bad.

        • hex13 8 years ago

          I've created library `transmutable` for performing automatic copy-on-write behavior in JS (you just write imperative code which is transformed behind scenes into immutable updates https://npmjs.com/package/transmutable

          This can avoid boilerplate traditionally associated with immutable updates in JavaScript, because you just write

              const copy = transform(original, stage => {
                 stage.someArray[index] = 42;
              });
          
          and it returns immutable copy of original object with appropriate mutations.
        • keymone 8 years ago

              (set arr 3 "New content")
          
              (set-in
                deeply-nested
                [arbitraty path to the element]
                "New content")
          
          convenient updates of immutable datastructures are possible.
        • gr__or 8 years ago

          if you use ES2015:

            arr = [
              ...arr.slice(0, 2),
              'New Content',
              ...arr.slice(3)
            ]
          • roselan 8 years ago

            In my eyes this slice of code is even worse than the array map one, where there is 2.5 pieces of logic (map, if, and 2 return that makes for the .5).

            In the version you have 2 spread operators, an array construct and 3 hardcoded ints.

            I might not use the correct academic terms, and I might not be yet fully accustomed to es2015, but this way of writing stuff always make me pause and double check the code.

            • mwigdahl 8 years ago

              In ES2017 this gets substantially better:

              const arr2 = Object.values({...arr, 3: 'New Content'});

coldtea 8 years ago

Judging from the title I expected one of the usual BS posts like "OMG, React mixes code and html!!!" etc and was ready to post a "No, you just don't get it" comment.

But this actually makes several good points on accidental complexity imposed by React/Redux.

I know why they impose it, but there must (should) be a better way.

bichiliad 8 years ago

There's a lot of comments in here addressing some of the conceptual misunderstandings of "how to use react" (i.e. "use immutable.js", etc). I started writing React within the last year and, while I still find parts of it strange, I've found its real strength comes from the fact that it's easy to reason about, particularly at scale. In a large project, I don't find myself digging around the codebase looking for the place where event listeners are being bound, or where a piece of the DOM is getting mutated. The unidirectional flow of data makes it very easy to jump into a piece of an app.

It's not without its complexities, however. Mainly:

1. using JSX, instead of a more transparent templating language, means people with less technical knowledge (i.e. product designers) have a higher barrier to entry when trying to make simple UI changes (I'm looking at you, `className`).

2. it is unclear at times whether a component should have its properties passed in directly from state through `mapStateToProps`, or from a parent component through `props`.

3. there does seem to be an tiring amount of boilerplate when adding a new piece of interaction to a component (an action, an action type, a reducer case, and usually a piece of state all need to be added).

4. to a newcomer, the benefits of immutable.js are apparent, but the benefits of a memoizing layer like reselect.js were less obvious. When you're still trying to wrap your head around How To Write React Things™, it's not apparent that you'd even need memoization ("isn't React supposed to be good at diffing stuff?" you ask yourself after watching large pieces of your app redraw itself over and over).

I'm curious to hear how people deal with these particular issues. React was one of the more useful tools I learned about this year, and I'd love to see the process for newcomers to React become less frustrating.

Edit: formatting

joncampbelldev 8 years ago

If the author wishes to continue with js/react/redux then he needs to pick up a library like immutable.js to cut down that immutabiilty helper crap.

However, there is a better way ... lein new figwheel my-app, clojurescript+reframe gives you all the benefits of redux with an order of magnitude less boilerplate (also hot reloading and immutability by default without no extra setup or ceremony)

  • gorm 8 years ago

    Immutable.js is just another complication with another 60k size penalty with a few new negative drawbacks that he would need more complexity to solve. Author is already arguing against this approach.

    • BigJono 8 years ago

      Yep.

      I've been working with React for years now, over several large projects. I still feel like I'm not used to it, and I still hate it. That's not normal.

      We need to either figure out how to do this shit with mutable data structures, or we need a new language that's immutable by default.

      ImmutableJS blows chunks. Yeah it "saves" code until you start doing the data transformation dance trying to figure out when and where to convert between plain JS objects and Immutable ones. Then you end up with some real ugly shit that'll trip up every new hire you walk through it (we use a higher order component that converts a component's Immutable props to regular objects, which incidentally is another import that like 800 unrelated files depend on...)

      God help you if you don't use well commented code or Hungarian notation to differentiate between Immutable objects and regular ones. We all know how long good commenting practices last without thorough code reviews, and we all know how long those last in fast-moving environments, which is where React is most useful.

      I guess a typed language would solve that. No, Flow and Typescript don't count.

      • joncampbelldev 8 years ago

        Did you say "immutable by default"?

        fanfare, fireworks, etc

        CLOJURESCRIPT!!

        sorry I just get really excited when I can mention it ... I'll go now

      • mamp 8 years ago

        Why don't Flow or Typescript count? Our team uses TypeScript, mostly C# devs, it's been great. The main issue getting definitions for some less common libraries.

        We haven't been using immutability.js because of the back and forth overhead between regular JS and immutable objects. Instead we use mutation checking of the Redux store during development you can make sure nobody is stomping on it by accident.

        • BigJono 8 years ago

          > The main issue getting definitions for some less common libraries.

          That's one problem. The other is discipline. It's just way too easy to opt out of the type system. It shouldn't be a problem, but in the world of deadlines where every single front-end dev is intimately familiar with writing plain old Javascript, it is. All it takes is one manager that's a bit pushy, or one urgent production bug, and your codebase is on it's way to turning into a pile of shit.

          I do love type systems, but IMO they have to be part of the language, it just doesn't work as an optional addon.

    • joncampbelldev 8 years ago

      60k is hardly an issue, most hi-res images would be larger than that.

      Plus due to the google closure compiler code can be minified with an aggression unknown to the typical js minifiers.

      Add to that tree-shaking (removing unused code) and the long term size of your app is looking good.

      I find clojurescript and specifically figwheel reduces language annoyanes and tooling problems. No more do i have to jump through hoops to get a project setup, or pick the latest and greatest build tool (grunt->gulp->webpack->jspm)

      • mariusandra 8 years ago

        60k is a big issue if your users are on older smartphones. I'm tired of people equating the time it takes to download an image in the background with the render blocking cpu-crunching parsing that javascript requires.

        • boubiyeah 8 years ago

          Word. Such a stupid comparison.

          You can add JIT too :) More JS, more time needed to reach decent runtime speed post JIT. React's first render is very slow.

          • joncampbelldev 8 years ago

            A one-off event for a single-page-app which is likely to be used for more than a few minutes, and if performance of old mobile users matters then a native app is necessary, period.

            If you're talking about a webpage then yes that would be awful.

        • joncampbelldev 8 years ago

          Like the 966k of JS on your homepage? ;)

          There are several things to consider with download time:

          - is this a website? why on earth do you need react or anything for a website?

          - is this a single page web application? then to develop with a medium sized team and an increasing feature set its nice to pick a language and library/framework that enable that.

          - do you really care about mobile users performance and bandwidth? then you need a native app

          This is all unrelated to the article, which is merely an uninformed rant about someone who doesn't understand the point of immutability and its use within functional programming as opposed to shoe-horning it into imperative code.

          • menckenjr 8 years ago

            Your point about the need for a native app is going to raise hackles on web devs who want to "do mobile development" without paying their dues by learning the platform.

      • ryanlaws 8 years ago

        I was trying to get into ClojureScript a few months ago, intrigued by the tree-shaking of the Closure Compiler. I was thoroughly disappointed when my compiled hello-world yielded compiled code in the neighborhood of 70k. Surely I configured something poorly or didn't install the right leinegen packages, but coming from webpack this is a pretty discouraging out-of-the-box experience.

        It seems there's some minimum (think Greenspun) JavaScript necessary to have a working SPA that handles DOM manipulation, network communication, state management, module management, events, et cetera, somewhere between 50k and 100k. I would love to be proven wrong about this. Maybe as native ES6 (or WebAssembly) becomes the norm this will be less the case.

        • joncampbelldev 8 years ago

          There certainly is a minimum, especially when bringing in another language entirely. The point of the google closure compiler, with advanced opts, tree shaking etc etc is that the size will grow slowly as you add hundreds of your own source files and dozens of 3rd party libraries.

          Choosing libraries shouldn't require careful examination of their output file size, especially if you only want half the functionality.

          • ryanlaws 8 years ago

            Are you implying then that the Closure Compiler mitigates or even eliminates the need to carefully examine the output sizes because of its optimization capabilities? If so, that's great, but I do remain skeptical about this, based partly on my experience described above. I don't mean this in a sarcastic or dismissive way but I was expecting to see something along the lines of:

            console.log("Hello world!")

            I realize this is a silly example for such a powerful tool but I just wanted to quickly get a feel for what the compiler is capable of before I committed a whole lot of time to learning the language. All I got out of the exercise was that the compiler creates a much larger minimum package size than I'd hoped. I'd appreciate any suggestions on a better way of proving its value for the cautiously curious. The language itself seems great, as does the community.

            Perhaps it's just a different paradigm from npm/webpack, e.g. utilizing a rich built-in library rather than, yeah, carefully grocery-shopping for only the components you need? I'm not saying one is necessarily better than the other but it does intuitively seem that choosy shopping will tend to yield a smaller package size, at least for small-to-medium applications.

            • christophilus 8 years ago

              Clojurescript's bundle size for real world apps is decent, especially given the power it provides. If all you're doing is a 3 line JavaScript, Clojurescript won't benefit you. But if you're writing a complex application,it will beat or match your typical JS stack in terms of code size.

              I suggest watching this:

              https://m.youtube.com/watch?v=gsffg5xxFQI

    • eknkc 8 years ago

      https://github.com/rtfeldman/seamless-immutable is easier to use with 7kb minified size.

  • fulafel 8 years ago

    Yeah, if you're going through the trouble of using a transpiler, it's not clear why you'd stick with JS. Especially since Clojure gives you the option of using the same language on the frontend and backend, same as a JS frontend + Node.

  • christophilus 8 years ago

    I was just going to say this. Clojurescript+re-frame+figwheel is brilliant. It even has a good way to handle ajax and other async operations.

Tade0 8 years ago

I think the author may like to consider Vue.js + Vuex. In Vuex in particular the first argument of each mutation is the store state, which you can mutate how you wish and the framework takes care of the rest.

  • overallduka 8 years ago

    Yeah. VueJS is powerful, easy, and made based on Javascript principles itself. I recommend for sure for who thinks React overcomplicates stuff, like me.

mamon 8 years ago

Maybe this is stupid question, cause I don't know React or Redux, but why would anyone want the data structures holding page data to be immutable? Data can change any time due to user actions, immutability would only get in the way, wouldn't it?

  • VeejayRampay 8 years ago

    Because if everything is immutable, it gets very easy to compare two given states and know when and what to update, by using referential equality (if you create a new object every time, then a different "ID" means the data has changed, to grossly simplify the idea behind it).

  • romanovcode 8 years ago

    The "redux" way is to make everything immutable to reduce side-effects, implement time-travel debugging and most importantly - make your code very complex.

    • joncampbelldev 8 years ago

      Immutability in js is awful hence the complexity, a library like immutable.js can make it better, but the language is just not built for it.

      Because imperative code and persistent, immutable data do not play nicely together.

      • romanovcode 8 years ago

        Agree, but the problem is that you need unreal discipline because what I see in projects that are 1+ years old half of the code is using Immutable.JS and half is not - and that is even worse!

    • davidmurdoch 8 years ago

      Haha. You just made me choke on my coffee with that last line!

anilgulecha 8 years ago

I get his point -- javascript object observation has been a pain, and causes the stated workaround.s

With new API like Proxy [1], we should not be able to just modify data as needed, and any observers can be notified by handlers in the object get/set. This will lead to data being fully mutable.

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

franzwong 8 years ago

Choose the tool which is suitable for you. When your web app grows to a certain scale, you will need "lots of code" to maintain state and prevent rendering.

agentultra 8 years ago

> This is probably an ill thought through rant but...

Everything after the "but" and all.

The whole point of Redux is to separate actions and state manipulation. An argument that, "well I want to manipulate variables feely," is not an argument. Just don't use Redux. End of story.

The pattern doesn't come from React. There are many patterns in React that are just Monads by a different name. Redux isn't much different.

thenewvu 8 years ago

React does its job fine. I think the good part of the post is pointing out the verbosity of Redux and you don't accept it. According to me, it totally depends on your implementation, Redux is just a concept of data flow, you made your choice when using react-redux. By time and eventually, you will figure out how to minimize the boilerplate, because you didn't accept it.

LoSboccacc 8 years ago

Without a big push in uniforming and standardizing ways to listen to property changes on both objects and components there won't ever be a sane UI framework in javascript, it's simple as that.

They'll either be too limited so that you cannot express the full featureset of html within their bindings without hacks or too convoluted to use and impossible to debug.

skilesare 8 years ago

I've tried to 'get' redux a couple of times and have reverted back to reflux each time because sanity is nice.

mariusandra 8 years ago

Try using ES destructoring and spread operators plus a library like Kea (https://kea.js.org) to provide a framework over Redux and most of these arguments become irrelevant.

  • davidmurdoch 8 years ago

    Not the author, but my opinion on the matter is that react already has too many abstractions and helpers, which just adds to the problem. React is difficult to grok on its own. Adding another framework to the tech stack just makes it worse if you don't already have a fluent understanding of the layers beneath. This is my experience with it, at least.

    • mariusandra 8 years ago

      But that's kind of the point with react: it's just a view library so you're forced to add things to the tech stack until they click together. Of course it helps a lot of you know how all the layers work on their own.

websitescenes 8 years ago

Honestly, I don't recommend using React unless you're building realtime web applications. Otherwise, you're correct, React is too heavy. If you're not doing realtime, the idea of state is completely unnecessary. But if you are doing realtime web apps the idea of state and hoops that React make you jump through make sense. Is it hard? Yep. Is it worth it. Yep. Will there eventually be a better way? Yep. With that said I think some of the pain points you identified could be simplified. State is needed but immutability could be made easier.

luord 8 years ago

After reading so much about it and trying it several times, I think my problem with react (alongside the licensing issue anyway) is that it feels like the perfect example of the fundamental theorem of SE: Everything is full of indirections and, when that isn't enough, then more abstractions in the form of tangentially related libraries (such as immutablejs in this thread) are recommended.

I'm sticking with Vue, it's not perfect but it was at least designed to play with js's strengths instead of abstracting them to shoehorn functional principles.

amelius 8 years ago

Could somebody outline how I can write an efficient rich text editor using the state management techniques of React and Redux?

(Not that I want to try this, but I'm interested in how that would work).

shafyy 8 years ago

I agree that there is some amount of boiler plate code to Redux that doesn't seem to make sense and takes a long time to do when you're new. But I think it really helps with maintenance and scalability of projects down the road and saves you time later on.

Of course, as others have said, React and Redux is not a panacea - depending on what you want to achieve and on your personal preferences there might be better tools.

  • hex13 8 years ago

    > I think it really helps with maintenance and scalability of

    > projects down the road and saves you time later on.

    It's popular argument but I don't think it's completely correct.

    On the one hand principles of Redux (immutability, message-passing approach, separation model from the view) can be helpful, on the other hand huge amount of boilerplate and moving parts can only spoil scalability.

    Besides Redux is very low level with very little abstraction (this is why some many abstractions over Redux appear - because Redux alone has almost none).

    I think Redux has good foundations but it's poorly designed as a library targeted to average developer working on real projects. It feels more like some academic experiment, something more like proof-of-concept that library that solves real problems in elegant way.

    • shafyy 8 years ago

      I see your points and don't disagree. However, Redux is a fairly young concept and I think it has some potential to grow (as is React).

tboyd47 8 years ago

This guy expresses a lot of opinions about React/Redux that I share, but he doesn't understand something fundamental about web development. The look and feel of the page comes first, and the structure and coherence of the code comes second. And you don't really need complicated, fast UI for most web projects.

  • coding123 8 years ago

    Yes, but I sense that he's in a similar boat as me right now. I just joined this team that's already using React/Redux, and the code quality is... very sad.

    • tboyd47 8 years ago

      Code quality was the main issue driving a lot of folks to React. Like lambs to the slaughter...

obfk 8 years ago

WHY would you even considering composing your own diffing structure for updating a components state when that's entirely against the paradigm React proposes. Pass props from the parents and let the tool do the heavy lifting. State is an abused and misunderstood interface in React.

littlecranky67 8 years ago

Author complains about "lots of code" needed for changing his data, but at the same time refuses to use modern ES6 features.Most of his code would come down to 2-3 lines when using destructuring and object/array rest operator.

  • bokglobule 8 years ago

    Agree. Some of the complaints get back to not really understanding the ES6-7 feature set that was created to allow JS to become more compact yet expressive in doing common tasks (like creating an object from an existing object, yet changing a few parts).

    For the Redux issue, the light bulb went off for me at one point on how best to use it to solve specific issues. React is focused on component based development of the UX; everything in the small library is there to help with this including "state" (that is, the internal logic state of the component). Since React went with the simpler one-way flow of data updates (vs. Angular's two-way), Redux came along to help bridge the divide between clusters of components that share some data.

    So when designing React apps, I almost always use React state. 80-90% of the time it's fine, works well and is easy to understand since everything about the component is there (along with the "props" or arguments to the component).

    I use Redux when I occasionally need to do the following: 1) Share data between otherwise unrelated components 2) I need to setup "global" state that exists between page transitions, etc. 3) A child component needs to notify a parent of some event. This can also be done with a simple callback provided as a prop to avoid Redux in this situation.

    So think of this in two levels - local component state within a nest of related components, and shared state within a set of unrelated components; the latter is where Redux can help.

    I much prefer (and find simpler to understand) that state is local and changes one-way. It's similar to the issue whether a language supports reference types as parameters or sticks to value types. Reference types make it easy to pass along side effects to the caller, but it can also introduce hard to understand side effects.

keymone 8 years ago

yep, let's all just get back to mutating everything everywhere and generating dom elements in arbitrary places. because it has worked so well for us in past 12 years.

i get a feeling author had no prior experience with js ui whatsoever.

sotojuan 8 years ago

Not the biggest JS fan but this is ill-informed and poorly written. Sounds about right for tech blog posts at least.

romanovcode 8 years ago

Some people like immutability, some don't. It's the way of life.

pushcx 8 years ago

This example doesn’t fit with the React style I’ve seen before, where state is rarely used. This data isn’t flowing (https://lobste.rs/s/ptfoib/yes_react_is_taking_over_front_en...) like I’ve come to expect, but one of my biggest gripes with React is that the docs are no longer very good because they haven’t been comprehensively rewritten for the current design and because the only sentence in the docs to address the crucial distinction between props and state is the distinctly unhelpful:

> If you imagine a component tree as a waterfall of props, each component’s state is like an additional water source that joins it at an arbitrary point but also flows down.

In this post’s example, I would expect to see a component for an individual Person with the props name and location, then a People component storing the ordered list in props. If the app does a lot of this general “maintain a sorted list with random insertions from over the net”, People would be wrapped by a higher-order component (https://facebook.github.io/react/docs/higher-order-component...) managing that. Otherwise there’d probably be a page-level custom component or just random stateful javascript pulling in the data and passing it down to People for rerendering. (I don’t know Redux to address the second half of his example.)

It’s ironic that the author advocates for immediate mode GUIs, because normal React looks and works like an immediate mode GUI with memoization. A component is a function responsible for part of the page. Its props are the input to the function and it returns a render of part of the page (possibly by rendering more memoized components). The cache is busted when props changes. There’s also a hack to be used sparingly called state so that small bits of UI state can be managed at a low-level instead of in their parent component.

Nekorosu 8 years ago

Somehow author jumps from the problem of convenient data structures updating and immutability to Redux which solves a different problem.

There are several things about React, Redux and React based tech stacks:

1. React requires knowledge of basics of functional programming

React looks like it's easy to pick up but if you don't know or want to learn at least basics of functional programming then it's not for you. Without this knowledge, a lot of things will be a struggle and won't make any sense. You'll mess up pretty bad. React requires the understanding of its principles which require the understanding of FP essentials.

2. React is not a framework and does only one thing well

It does only one thing well, turning your UI into a function of data. Yes, there is a virtual DOM but it's an implementation detail and not the purpose of React. If you think about it everything which is there is needed to make that UI=F(data) possible. However, it's enough for simple apps.

Immutability isn't always needed so it's optional. It's not built into JS, you'll have to use an additional library.

3. Building non-trivial apps requires a lot of knowledge and experience

Building non-trivial apps with React only is a pain. That's expected because the only thing it does is making a UI a function of data. It's not a framework with a complete set of tools and practices for building a whole SPA. That means you have to assemble your own tech stack for your particular task. This requires a lot of experience but lets you have the tools which are a better fit for your app.

Redux is just one of the available choices for solving the problem of complex app's architecture. It isolates state from React components. UI interaction with the outer world is behind actions. Data access is behind selectors. State mutations are centralized in reducers. This is very convenient, you always know where to look for something. Business logic part is very clear because of actions and reducers. Not messing everything up requires knowledge and discipline though.

The funny thing is React+Redux isn't a complete framework. For case, there are several solutions for writing asynchronous actions.

The main idea is React is ok to use by itself for simple things. You don't need to know much except FP essentials. Using more advanced React based tech stacks requires much more knowledge and experience.

If you don't know which of your problems React solves you don't need it.

If you don't know which of your problems immutability solves you don't need it.

If you don't know which of your problems Redux solves you don't need it.

  • coding123 8 years ago

    I completely agree here. and I think if most people followed these last 3 lines, there might be what, 6 projects using React?

    I find the highlighted article on Facebook's "reason" for inventing Flux/Redux very laughable. - This message unread indicator kept saying (1). And how it went away with bug fixes and came back...

    Did they ever stop to realize they just had some really bad devs working on the chat app? Any re-write, whether they had to invent flux or not would have fixed that indicator. It's a false story.

    • Nekorosu 8 years ago

      Much more than six projects for sure. Nice pun though. I started using React before the hype train. I couldn't care less about Facebook's reasons but I enjoy the fact they somehow built a library which is a good fit for some of my projects.

      I don't like Redux that much. All React based frameworks I like are not even written in JavaScript.

williamle8300 8 years ago

Seems like the source of his gripes are with functional programming, not ReactJS itself.

sambeau 8 years ago

TL;DR: Author confuses Redux for React and then rants about it.

halayli 8 years ago

It doesn't feel op have done their homework well.

You should check immutable-js.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection