Things Reacters do that Re-framers avoid
purelyfunctional.tv
purelyfunctional.tv
I didn't get much out of the article since gripes 1-5 are all solved by Redux, and 6 is a complaint about Redux having too much boilerplate.
It also seemed to me that mapStateToProps and mapDispatchToProps aren't given a fair representation in this article (especially with the "selector" pattern emerging within them). If your Redux store is denormalized already, then yes, mapStateToProps will seem quite redundant. However, if you're working with multiple sets of async data, it's much easier to organize your store by fetch method and denormalize inside mapStateToProps.
Also, my own personal advice is that you should always use the "object shorthand" version of `mapDispatch`, and never actually write a real `mapDispatch` function by hand again:
const actions = {addTodo, toggleTodo};
export default connect(mapState, actions)(TodoList);
[0] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...Some of us are just lucky, I guess.
I can appreciate the idea of teaching functional programming only after I graduated, but for starters, it seems too far away from what the industry, magazines and people talk about. That might be a reason why it's not taught at many schools.
The popular ressurection of functional on frontend is relatively new development. Before, it was used only in few math related areas.
At least this item comes off as a straw-man argument. Reacters also want their views to be pure. They do not typically load data in presentational components, and it can be easily avoided.
That said, granted: Clojure, Elm et al. achieves purity and immutability in a simple and clean way JS/React/Redux can only approximate. The latter is for the dirty pragmatists among us, I guess.
People who have been bitten by it (or read enough best-practices stuff to avoid it up-front) will know better and won't do so, but you have to know better - that's kinda the central point in here. React has more footguns, and the article is arguing that they're unnecessary / things end up worse than if they weren't allowed, without losing flexibility.
The author obviously comes from an MVC background where a component is one specific aspect of an application, and enabling it to do all these other things seems sacrosanct. But they've got it backwards.
Think of a React component on the same level as a function: we design our functions as purely as we can, but it's not the function's fault if it's written poorly.
This is just like earlier versions of Java which didnt have enums or lambdas, but used classes for everything. See what's happened now.
[EDIT: Regarding "everything is a component"] And this is a weakness. If everything is a component, everything is tied to the React library/ecosystem.
It would be better to treat everything as a primitive - like, say, a function. My data stores are functions (closures), my styles are functions that return data structures, my views are functions that return components.
IMO the craze that struck a lot of the React ecosystem (everything's a component! State is a component! Routes are components! Side effects are components!) is dying down and people are realizing that it's better to stick to things that are much simpler and has first-class support from the language. Tying yourself to React (or any one technology) fundamentally limits your capabilities and expressiveness, and also makes your software very brittle.
This is why, IMHO, most JavaScript devs actually would be much happier writing in Clojure(Script). The language provides first-class support for so many things that JS devs have to reach to libraries and frameworks for, e.g. immutability, CSP, pattern matching, and actual functional constructs like transducers.
At first there were lots of boilerplate code, and lots of kind-of-similar-but-different code all around. After each project, I extracted and generalised the helper components/methods/systems to create my own 'framework', and now I have a foundation that eliminates most of the pain points that people experience with react/redux, that's specific to the way I develop software. Thats why I love React and surrounding ecosystem, it allowed me to choose the relevant libraries/solutions that fits my workflow.
Here is my thoughts about the points in the article:
1. Reacters load data on mount
In my components, I just declare the data that it needs, and the relevant system loads the data and sends it to the component via props. (like Relay) No requests happen in the component directly. When you have only a few components that needs data in your app, fetching it in the component works, but when you have a complex app (I build ERP systems) you need a centralised way to handle data fetching.
2. Reacters register a bunch of event handlers in their components
Declarative event-binding works great for me (similar to react-event-listener[0]). Instead of adding the subscribe/cleanup logic to every component, I just declare the events I'm interested in, and just add the relevant handling code to my component.
3. Reacters optimize when to render
Using redux and never overwriting the store takes care of this for me.
4. Reacters load data when stuff changes
Same as 1., yon can declaratively state what you need, and the relevant system can handle the rest of the logic without changing anything in the component.
5. Reacters worry about when to set state
I'm not sure if this is really a problem, especially when you learn how the lifecycle hooks work.
6. Reacters use a lot of Redux boilerplate
Redux has a goal to keep things simple, and let users choose the relevant 3rd party solution to your needs. It means that you need to do some work to create a no-boilerplate solution, but in the end it will work flawlessly according to your needs.
In my 'framework', I generate the store definitions and action handlers for my database models automatically from SqlAlchemy model definitions, thus eliminating 95% of the boilerplate.
I know that there are frameworks out there that eliminates the need to create your own solutions to most of these problems, but I've found out that, when you try to go out of the 'blessed' path, you will be banging your head to the wall more times than you want. With building my own solutions around the react/redux, I'm in control of the things that I care about. When you control the 'magic' part of the stack you use, you have a lot of power in your hands when problems arise.
[0]: https://github.com/oliviertassinari/react-event-listener
Let's say I have a box with 1000 items. It will take some time to load, so those 1000 items should not be painted in one go (freezing the UI), but instead be shown incrementally, from top to bottom.
Imagine that while it is loading, I can click a "delete" button on one of the items, so that item would disappear while the list is still growing at the bottom.
I experimented with this myself, and the UI designer I worked with thought it was not pretty when the screen turned blank while scrolling rapidly.
The problem I had was that painting the items in the viewport took already more time than the allotted time per frame.
Whether the placeholders look any good is a different issue. We generally thought they looked / transitioned to real content a lot worse than showing nothing, and eventually just ripped them out. But e.g. Pinterest did it fairly successfully for a long time (they tended to replace images with a solid image-background-color so the content just kinda emerged. neat effect, but works far better with product images than user-generated content :) )
But ultimately, when you exceed your tolerances, you have to render something or nothing, or disallow it (e.g. block everything). You just have to choose which one. The point where you exceed will shift depending on what you're using/doing, but it always exists.
[0] https://bvaughn.github.io/react-virtualized/#/components/Lis...
The simplest solution might be to use a placeholder. You might also want to track how much time has passed, so you can stay at 60FPS.
If it takes a long time to render each item, you might consider using a placeholder and caching existing elements. Be sure to track how much time is spent rendering so you run at 60FPS.
For the most part, this is what this reframe thing aims at as far as I can tell.
Setstate really should be long term deprecated, it's a design error in react.
I think it's easy to say it was a design error with hindsight. I'm happy React came along, and in the future it will either get better or we'll move on to something else, heaving learnt from it's mistakes.
New technologies like react either need to fix their problems like lack of integrated state management or be replaced by something that does do it right.
The criticisms of the linked post are valid.
Mayhap each simplified something, but the result is more complex. Frighteningly so.
People don't work towards reducing complexity in large applications (which involves trimming dependencies, removing api surface area and minimizing interactions between different people's code, which is all hard), they work towards reducing complexity in simple toy applications (which is about cramming as many tools in until you can do exactly one specific thing in one short line and it looks nice).
That has the effect of reducing complexity at first glance, but increasing it in real world applications.
Databases come to mind. Collections libraries do not. :(
This theory is correct. It explains why virtually nobody ever uses C, let alone C++, and all of our internet infrastructure is built on top of Scheme.
Integrated state mgmt is out of scope for React JS per se. Some ppl feel mobx is a better approach than redux. They're free to mix n match libs to suit their prefs. The React ecosystem is a set of libraries; by definition that entails more choices, more "fatigue", more combinations of approaches, and more innovation, compared to all-inclusive frameworks like Angular. Don't get me wrong; Ng gets some things right, and there are valid reasons to deliberately limit choices and go all-in w/ a framework. But I respectfully disagree thst React "needs" to integrate state management.
A "better react" would make it natural and obvious to use store versus local state in the appropriate way.
The problem is that, with Redux at least, composing data stores is a major pain. The only pattern supported out-of-the-box is horizontal slicing (have different reducer for separate pieces of data). This may work for separate pages, but it does nothing for you as soon as you need data sharing. I don't think React itself should change, but I haven't found a really satisfactory solution to the problem of sharing stored data.
requestAnimationFrame(() => dispatch('TICK', Date.now() - prevTick))
Then you can feed the offset into view functions which forces a re-render and steps the animation.