9 ms·
The Simplest React Stack – Part 1: Bootstrapping and State Management
- molly0 9y agoget completed () Is "get" som es6 thing?
- thenewestkid 9y agoIt is actually ES5: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... In a nutshell: it is used for computed properties, which compute their value on 'get' operations instead of storing them.
- RobertKerans 9y agoNo, just not commonly used; getters and setters aren't terribly useful in a language that allows such easy direct modification of objects (as opposed to say Java)
- Symen 9y agoBut transparent getters and setters can be used to emulate private or immutable properties: function Foo() { var _bar = 42; return { get bar() { return _bar; } } } var foo = Foo(); foo.bar /* 42 */ However the fact that you can transparently replace a simple property by a computed one (e.g. for backwards compatibility or to trigger side effects in observables) does make explicit, Java-style, getters and setters less useful.
- _pdp_ 9y agoIn our shop where we have built many high-performant, and pretty complex (various types of security tools and all that) react apps, the state is managed at the top-most component and it is passed down to all other components as props. It works great and it is functional all the way.
- arc_of_descent 9y agoSo you pass the entire state object, however large it might get to all child components?
- girvo 9y agoFor child components that don't need the entire object, leverage destructuring assignment and it becomes a lot nicer than it sounds!
- realharo 9y agoSo how do you deal with UI containers that don't really care about most of the state, but still need to pass it on to their child components? It sounds like tracking this by hand ("what is needed where") could get messy, though I don't have experience with this approach.
- arc_of_descent 9y agoIts turtles all the way down!
- jcelerier 9y ago> So how do you deal with UI containers that don't really care about most of the state, but still need to pass it on to their child components? That's more or less the questions that they were asking in 1995 when they made the design patterns and conceived dependency injection.
- shados 9y agoSomeone else beat me to the joke of "turtles all the way down", but that's mostly it. I'll first refer to this Twitter thread: https://twitter.com/JEG2/status/902534133427134465 https://twitter.com/JEG2/status/902534133427134465 Now, the reasoning is: if you pass everything down, then things get interesting to reason about. Given a state to a component, it will always render the same way (give or take, local state and all). That is only true if you reason about children components as implementation details of the parent. That is, if a parent component renders a child one, and the child needs a prop, the parent should have that prop too. Otherwise, you could render the parent 6 times with the same props and get 6 times a different result based on some undefined (at the parent level) magical global side effect. Doing it this way makes your component tree essentially fractal: at any point you could detach an arbitrary component, put it in a library, and use it in another app: there's no assumption. Any part of the app is in itself a small app. Now, the main issues is the boilerplate of typing it all out (which is minimized if you use a single "model" object at every level and either pass it as a whole, or a smaller part of it, to any child): if you use regular props for every value, you'll have top level components with 100+ props. The other issue is maintenance. What happens when you move things around. That part really begs for a type system. Use Flow or TypeScript, and just let the compiler bark at you. When the compiler is done barking, you're done fixing, and you have a full statically checked view of your model dependencies. That's awesome! The rest is mostly cultural. At which point does a developer throw their arm in the air and say "I don't want to do this!". A few months back, Jordan Walke did an Ask Me Anything on Discord where he said he had a pretty high tolerance for passing stuff down manually. I assume that explains some design decisions in React (eg: like how context was not a first class citizen earlier on), but I don't want to put words in his mouth. For an example of this concept, look at Elm, where that's the primary way to build things. A fully fractal architecture where models come from the top and get passed all the way down to all the turtles. The way you build your model changes a bit (in apps Ive seen, it's more of a mirror of the component hierarchy, and less of a conceptual, normalized model), but boilerplate isn't that bad. Higher than the typical React/Redux dev will tolerate, which itself is higher than what most web devs will...but people who do it generally end up with very high quality apps that are trivial to maintain.
- whalesalad 9y agoSurprised to see the state store caring about events. Checking for a keycode in your system to add an event to a store feels like a violation of separate concerns. That was an immediate turnoff for me with this post.
- thenewestkid 9y agoValid point. You can move that logic to the component and leave the store for pure data manipulation and handling only. I do that for bigger projects, but in this case I wanted to make things short. The goal of this series is not to teach patterns but to promote a simple and flexible stack that you can use with the patterns that you like. (In your case you can move the view specific logic to the level of the components).
- cies 9y agoI came here to say the same as whalesalad. This is not just a "you can do that if you wish" situation. This is more a case of "so much anti-pattern that it turns off readers".
- thenewestkid 9y agoAs you wish (: You convinced me, I edited the gists and removed the antipattern. Please review it if you have a spare minute. Thx!
- cies 9y agoMost welcome. Looks so much better. And it was whalesalad to report it first :) Have a great day!
- vosper 9y agoI have wondered if it would be good for debugging (assuming you're using Redux or something with a time traveling debugger) to put UI events in the store, too. Then you can have a complete picture of "how did we get to this broken state"if you need it. I would keep that stuff separate from data with a prefix, so that you could easily distinguish between the two.
- jbergens 9y agoNice idea! Did you check out mobx? My guess is that it would be almost as easy and a bit more mature.
- thenewestkid 9y agoSure, I know about MobX. I use ES6 Proxies instead of the getter/setter based transparent reactivity they use. It allows me to have less edge cases in exchange for narrower platform support. MobX is also moving in the Proxy direction with v4, but I do not agree with some of their architectural decisions (mostly the synchronous execution), so I made a separate library. We can discuss these later if you are interested.
- faitswulff 9y agoNeat. Did you get any inspiration from Vuex in creating the store? The global store and building it out of a POJO are pretty similar patterns that I happen to like.
- thenewestkid 9y agoNo, I have never used Vuex, but I think Vue is an awesome framework. My main inspiration was monitoring my problematic situations and state management needs during app development in various frameworks.
- sigden 9y agoI'm a big fan of react-easy-state. Unfortunately its foundation of ES6 proxies precludes its use in Internet Explorer.
- yttrium 9y agoWhat about react-easy-state stops you from transpiling to ES2015?
- thenewestkid 9y agoAuthor here. As sigden mentioned, ES6 Proxies can not be transpiled. That is one reason why they are not yet commonly used. You can find out more about them here: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy https://developer.mozilla.org/en/docs/Web/JavaScript/Referen... (They are pretty awesome).
- packetslave 9y agoor Safari < 10 (Sierra)