To me, the application wide bus paradigm is elegant, and find it surprising that redux is currently more fashionable than this approach.
Thoughts?
To me, the application wide bus paradigm is elegant, and find it surprising that redux is currently more fashionable than this approach.
Thoughts?
Components can post messages to the worker to request an action on the state that will most likely change its data, but they can't edit the data directly, and props are only emitted if there is really a change in data.
Inside the worker, state is stored as immutable data, and action handlers are only allowed to make one non-async change (because the return value is the modified state). If it needs to do multiple things (e.g. download then process the result), it must schedule another action when it's ready to do the sync operation. This splits into granular easy-to-test operations on the state.
That way, it limits React (or Preact) to rendering (so it can also be used with other libraries, e.g. WebGL), and you can record the messages going through the worker to replay and analyze a scenario.
So far I'm happy with this setup, but I can understand the allure of thirdparty libraries instead.
As goes with every extra dependency: don't use it until you actually need it.
It's remarkable to me that real clients like Relay haven't caught on as much while Redux wastes so many peoples' time.
I will say that using it by itself is probably going to be challenging. You'll want to use a connector library (like react-redux in this case), invest in some good API middleware, etc.
Maybe it works on large teams and code bases, but it is unnecessary on smaller teams where sane code practices are enough.
The author of that post primarily claims that the main reason to use Redux is about keeping state in sync. That's _a_ reason to use Redux, but not the _only_ reason. Having a single store allows use of a middleware pipeline for centralization of things like logging, API calls, data transformations, and much much more. Having a single state tree and serializable plain object actions allows powerful developer capabilities like time-travel debugging, state persistence, and even synchronization of remote stores via transmitted actions. Use of "pure function" reducers is also key for time-travel debugging, as well as making it straightforward to trace where state changes came from, and are generally easier to test.
The author _is_ correct that a centralized store does make encapsulation harder to work with. That's a deliberate tradeoff. (Encapsulation isn't _impossible_ with Redux, but it definitely takes more work.)
Dan Abramov's article "You Might Not Need Redux" [0] discusses many of the common complaints about use of Redux, and the tradeoffs that Redux asks for and gives you. Also, my recent two-part post "The Tao of Redux, Part 1 - Implementation and Intent" [1] and "The Tao of Redux, Part 2 - Practice and Philosophy" [2] goes into detail on what actual technical limitations Redux requires and why, why common Redux usage patterns exist, and my opinions on the pros and cons of many "variations" in how Redux _can_ be used. (In particular, it's entirely up to you how much abstraction you apply, how you structure your codebase, and how much "boilerplate" you are comfortable with.)
Redux is certainly not the perfect solution for every problem, and it's generally not going to be the solution with the fewest LOC. However, it _is_ a powerful and useful tool for organizing your state and logic, and there _are_ valid reasons why its constraints and common use patterns exist (and complaints about those patterns rarely take those reasons into consideration).
[0] https://medium.com/@dan_abramov/you-might-not-need-redux-be4...
[1] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...
[2] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...
Redux does add complication. But it also cleanly solves a big problem. I've heard good things about mobx instead of redux in terms of reducing boilerplate/total lines of code. So that might be one thing to try if starting a new project today or refactoring.
The purposed solution in the blog is pretty bad. It only works if you have a few things being updated. It might work fine for the author's use case but it's a bad idea to assume it will work well for all use cases. If you want to go this route, please try Backbone.js and come back when you get sick of ghost event listeners (event listeners that didn't get unbound). Obviously, there are ways to work around those issues but it requires understanding them (both by you and any other devs who join the project -- some with less experience might have no idea about these gotchas).
1. It was there at the right time, when people started getting serious with React and were looking for a way to structure their data flow.
2. Tooling. Soon after it was released, the author demonstrated a pretty neat hot-reloading utility.
So no matter whether you're really into functional purity or are reminded of Win32 event loops, it was a practical solution.
If the tendency of the developer community is towards (faux) functional programming, why is the language taking a OO direction (with the community actively discouraging using ES6 classes)? Coming from OO languages, I'd like to use ES6 classes, but I can't because I'm told it's not idiomatic and I don't want my code to stand out like a sore thumb. So, "native" JS devs don't want to use ES6 classes, and OO devs gone JS cannot use ES6 classes without looking like fools; why is the feature there?
If you want pure OOP approach, check out mobx. It's a popular alternative to Redux.
Classes are just sugar over how devs were already doing class-like stuff with prototypes (see backbone/ember/angular etc). So I'd disagree that the language is 'taking an OO direction'.
> If the tendency of the developer community is towards (faux) functional programming
Wouldn't agree with that either. Some sub-communities perhaps. But e.g. in React there's a big push back towards using (class-based) Components and good old setState().
> I'd like to use ES6 classes, but I can't because I'm told it's not idiomatic
These people need re-informing! React Components and setState() are what Facebook use. In my opinion, setState() plus a router will handle the vast majority of state in your app just fine.
To get more of a feel for this setState() vs Redux kerfuffle:
Ryan Florence (of React Router) is a Components/setState proponent, and great person to follow on Twitter. I like his intro to this talk [1] where he talks about the issue. Also highly recommend reading 'Functional setState is the Future of React' [2]. And of course I think it's already been posted elsewhere in the thread, but Dan Abramov's own 'You might not need Redux' is definitely worth a read [3].
[1] https://www.youtube.com/watch?v=kp-NOggyz54
[2] https://medium.freecodecamp.com/functional-setstate-is-the-f...
[3] https://medium.com/@dan_abramov/you-might-not-need-redux-be4...
Simply, ignore them. That's just noise from the huge influx of JS developers and the immutable/functional cargo cult train. ES6 classes are perfectly fine, they're a sugary layer on top of prototypal inheritance, that merely formalizes how almost everybody was already using it.
Nothing wrong about ES6 classes, and nothing that great about pure prototypal inheritance anyway (which they still are).
>cannot use ES6 classes without looking like fools
For one, ES6 classes are the recommended way from the React team.
Second, don't worry about how you "look".
Programming is a discipline, not a cargo cult or pop culture to fear of being "uncool".
React, in its current form, requires classes or something class-like in order to implement stateful components with lifecycles. It also does not require that you handle data immutably - you can run `this.state.someArray.push(newValue); this.setState({someArray : this.state.someArray})`, and React will re-render just fine.
However, React also pushes you in functional programming directions: render methods should be pure functions, performance optimizations with `shouldComponentUpdate` work best if you've handled data immutably, and so on. The React team also plans to investigate a "stateful functional component" API at some point after the React 16 release.
It's also worth noting that React was not the only reason why classes were added to Javascript. There were hundreds of "pseudo-class" implementations out there already (all a little bit different than the others), and there was clearly enough demand for the concept to add it to the language in a standardized way.
Meanwhile, Redux has definitely helped popularize the idea of updating data immutably. The array spread operator was already added in ES6, and the object spread operator is nearing finalization. No, the language doesn't have full-blown immutable data structures, but handling data immutably is absolutely possible. If you don't like dealing with immutable updates yourself, there's Immutable.js (as you said), or dozens of immutable update utility libraries.
Particularly in the case of Redux, use of classes for data is discouraged because of the other constraints Redux asks you to follow. Plain serializable data is needed in order for time-travel debugging and persistence scenarios to work properly.
Overall, your complaints are split across a couple things. Classes exist because some JS devs want to use them. Functional-style approaches exist because some devs want to use them. Languages like C# and C++ have been "everything and the kitchen sink" for a while now, supporting multiple different paradigms in one language - Javascript is now the same way.
One of my favorite aspects of Redux is how easy it is to follow the flow of data. Whatever you do, you start at a dom element, look at what action creator it calls, and check out the changes in the reducer.
What kinds of issues and restructuring problems did you experience?
It's only on the larger apps with more complex customization where I have found the need to use anything other than the default webpack configurations other than the default create-react-app ones.