4 ms·
What an amazingly well-written, well-illustrated blog post. I really like how the post showed the contrast between "imperative anytime thing x changes remember
by stephen 7y ago
What an amazingly well-written, well-illustrated blog post.
I really like how the post showed the contrast between "imperative anytime thing x changes remember to poke thing y" vs. "declarative thing y is calc'd on thing x".
That said, I'm a little disappointed with hooks b/c, while React is not at all claiming they invented this declarative approach, it seems like other "state-of-the-art" approaches (like mobx? not picking that one as the best/only, but it's observer-/push-based) can do the same thing without the ugly duplication between "here's my calc on x/y/z" + "oh and my calc's array of dependencies is [x,y,z] which btw also doesn't use deep equality".
Like I get that it works, and it's built into React, so it's a for-free declarative/derived value/derived state approach vs. pulling in yet another framework, but I'm disappointed they couldn't (yet?) solve the "you also have to specify your dependencies/shallow equality" problem.
- JMTQp8lwXL 7y agoNot using deep equality allows for huge performance gains. You can use an immutability library like https://github.com/guigrpa/timm https://github.com/guigrpa/timm to handle mutations, if you want to edit a nested property on an object and return a new object.
- Ineentho 7y agoI haven't heard about timm before, but it looks very similar to immer https://github.com/immerjs/immer https://github.com/immerjs/immer, which is even recommended in the official React docs now
- acemarke 7y agoWe also recommend using Immer with Redux [0], and it's used internally in our new Redux Toolkit package [1]. [0] https://redux.js.org/style-guide/style-guide#use-immer-for-writing-immutable-updates https://redux.js.org/style-guide/style-guide#use-immer-for-w... [1] https://redux-toolkit.js.org/ https://redux-toolkit.js.org/
- tekkk 7y agoNice, thanks to both of you for the tip. I always hated ImmutableJS's clunky API which is partly the reason why I switched from Redux to Mobx as the object assigning felt otherwise so icky. I have to check out if Immer is any better =).
- ben_jones 7y agoPeople misidentify one of the biggest challenges of building a SPA in a startup, small, or medium, sized org: taming the horde of junior developers coming into front end development via self-teaching, bootcamps, and CS programs, who more often then not are writing significant parts of the product to be shipped. There is a huge need for them to have abstractions which provide structure and consistency without being hidden behind too much magic. React in general, redux, and hooks, to me all work to fill this need in a way which is superior to alternative tools. Specifically you can learn how they work in ten minutes or less. Of course ecosystem variety is critical and there are no doubt many cases where mobx, non-hooks, or similar implementations are the better solution.
- BigJono 7y agoI think you're totally right, but just want to point out. I'd never, ever rely on junior devs in a startup, for this exact reason. I can't think of a better way to totally ruin yourself than risk that. Build it yourself until you get funded and can afford the $200k or whatever the market rate is for experts. Startups succeed for the exact reason that they avoid the "average" team structure that bigger companies employ. You need a small team of experts, not a standard team of juniors with a few seniors. Beating the averages and all that.
- erikpukinskis 7y agoIt does seem crazy to me too! At best the jr developer is what, half price? 1/3? A good sensible developer, left alone, for sure will get 10x or 100x the work done in 5 years. But also.... The senior developer has Seen Some Shit, and is psychologically damaged. They will resist doing things a stupid way that’s still “good enough”. The Jr. developer will happily follow orders. That’s worth something too. Maybe the 10x comes back there. Probably diversity is worth the most. And just cut out bad blood, without prejudice, when it appears.
- WorldMaker 7y agoI've worked with frameworks all over the map in terms of dependency tracking, and right now I'd lean toward React's manual dependency tracking is probably the better approach as the default. Making it manual does mean that it is easy for silly mistakes to be made (missing a dependency or adding one too many), but it's a learning/debugging trick and eventually starts to become second nature. Tools can be built on top of this manual tracking to better automate it, such as edit/compile/pack time linters ("warn: you use this variable in this callback but don't include it as a dependency"), or additional meta-hook libraries at runtime that do some of the automatic dependency tracking magic (through Proxy objects or what have you). It's harder to fix some classes of mistakes/performance issues in the more automatic systems, and the classes of mistakes in the manual dependency tracking world are often easier to spot ("why isn't this updating?" when forgetting a dependency as opposed to "why is this updating too often?" with automatic tracking). I wouldn't be surprised if there aren't more automatic tracking tools that show up built on top of the basic hook pattern. My biggest complaint with the React dependency tracking is that empty dependency array [] has different behavior from null/undefined dependency array and so far I always have to look up which one I actually need and I just haven't yet written enough hooks that I've internalized why which behavior is which. It keeps the hook functions terse to write, but it's a small papercut.
- ratww 7y ago> My biggest complaint with the React dependency tracking is that empty dependency array [] has different behavior from null/undefined dependency array and so far I always have to look up which one I actually need I wish they had used a constant, like "React.everytime" instead of null. I rarely want an useEffect to fire on every render, but wanting it to fire on mount is very popular, to the point a lot of people have an `useMount` custom hook...
- winter_blue 7y ago> solve the "you also have to specify your dependencies/shallow equality" problem Isn't this a constraint imposed by the language? If they could reflectively inspect the code making up a functional component, they could determine the dependencies, am I right?