7 ms·
I use functional components only for things without state. If anything has state I use class components because otherwise you go mad. ;)
by jwlake 4y ago
I use functional components only for things without state. If anything has state I use class components because otherwise you go mad. ;)
- wpietri 4y agoCould you say more about this? I'm not a React user, but to me one of the OO fundamentals is "object = behavior + state". What you're saying sounds so obviously correct to me that I guess there's something pretty weird going on in React-land?
- yamtaddle 4y agoReact added "hooks" which are basically methods and properties implemented as FIFO queues instead of lookup tables, with terrible syntax that requires you to declare them inside their constructor (the "functional" component's... well, function). No, I'm not kidding. Unless something's fundamentally changed about the code since release, they even end up attached to an object representing the UI component, by the time the heart of React's runtime code considers them. It's some real Rube-Goldberg shit. I read the code because I read the announcement docs and was like "wait, it looks like they... but no, surely they didn't" but yeah, turns out, they did.
- nobleach 4y agoWhat's worse, they have interesting "rules" that one really needs to use a linter so their IDE/Text editor gives them friendly reminders. One cannot conditionally call useEffect. One needs to add all dependencies to useEffect's dependency array - BUT that has potential to cause infinite re-renders (especially when using a getter/setter pattern with useState). They encourage DEFINING functions inside of other functions. Years of CS education and practice go right out the window because some popular JS person on Twitter says, "it's fine". When pressed about it, be ready to be hit with, "You don't understand hooks".
- skydhash 4y agoI agree with the others. I've started using hooks since they were introduced and I've only hit the re-render issue only a few times, which I promptly fixed as they were caused by carelessness. My strategy is to not use a single useEffect, but multiple ones for each (which reduce greatly the dependencies). Also, avoiding dependency circles between useState and useEffect. I've used class components and I think hooks are much better than the monstrosity that the lifecycle methods would usually become. Also defining functions inside other functions is very much the staple of functional programming.
- imbnwa 4y ago>Also defining functions inside other functions is very much the staple of functional programming. Isn't the difference that JavaScript runtimes don't compile them away unlike functional runtimes?
- wiredearp 4y agoIn React terms, "functional" almost always implies the opposite of purely functional. It just means that the component is declared by a function instead of a class. First time you call it, the function can assign state that it may reference in future calls, not unlike the methods of a class. How they actually go about this is however almost entirely weird.
- bigDinosaur 4y agoClasses in JS are just functions anyway, and functions can have state. Saving the state of a function is a different thing, but of course JS allows that, too. Why is it weird?
- wiredearp 4y agoClass instances are objects and it's the objects that have state. Functions can only abuse themselves as objects to store state. function johnson() { johnson.state = {}; } This is however shared state and the state will be reset whenever the function is called a second time. So what you normally do with a function is to pass the state via arguments and now the same function can work with different states. React could totally do this via props or as a second argument. function Johnson(props, state) {} Instead they changed the laws of functions so that a function can act different the first time it is called and also be called the first time multiple times if and when the function calls a functions that looks like JavaScript but follow different rules [1]. This is weird. [1] https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at...
- bigDinosaur 4y agoAs far as I know, hooks use closures to store state, and that's neither abuse nor weird. Am I missing something?
- bobbylarrybobby 4y agoYes, there is something very weird indeed. Functional components are called every time they're rendered (that's not weird). But they have to maintain state between calls; they can't start over again fresh for each call/render (still not weird). So how do they do this? `const [state, setState] = useState(initialValue)`. You might look at that and think, I see useState being called, so it must be called on each render, so state is still not being preserved between calls. But here's the weirdness. useState knows whether it's already been called for a given component; this is how it tracks state. The first call returns the state (the initial value) and a setter. Subsequent calls -- occurring after the first render -- do not return these objects anew, but instead reach into a per-functional-component store and return the values that already exist there. Calling the setter doesn't set the state in the body; rather, it updates the value in the store, then triggers a re-render. If you're wondering just how react knows how to match up calls to useState between renders, it doesn't really. It simply matches them up based on the order they're called in. For that reason, you have to always call exactly the same useState calls on each render -- no putting some in an if statement or a variable length for loop, otherwise they'll be out of sync. There are a bunch of other "hooks" for use in functional components, but they all work basically the same way: place some data in the functional component's store, then set up re-render (which, again, just means calling the component's function again) to occur when certain data changes.
- divs1210 4y agoThat is bonkers, to be honest. I've used React a lot, but only via Reagent in ClojureScript. I think the JS people are being scammed.
- UlisesAC4 4y agoIt is bonkers. My number of "accidental" re renders on react are greater than before hooks. Before at least I knew what was called on boostrap moments. Now everything is run as a side effect when any dependency change. My needs on checking if a prop or a dependency has changed hasn't evolved at all. I just have the core of my side effects on useEffect.
- 4y ago
- jwlake 4y agoFunctional components are great in that they are more terse, less boilerplate. Class components just have more lines, more boilerplate, so they have a higher cognitive load. But when you have state, you have more complexity, you can't just wave your hand wave and make it go away. You need to take the complexity into account. Hooks are trying to do hand waving. The thing is, once you get to non-trivial use cases, the handwaving stops working. You're better off thinking a lot about where you state lives in your component hierarchy, and then limit your state to where you really need it. Once you do that the overhead of class components doesn't really make that big a deal. The same principle applies to almost everything in programming, the more thought you put into structure, the simpler you can make everything.