6 ms·
You're translating the class-based way of working in React against hooks, without stopping to consider understanding hooks as a first-class principle instead of
by nickdandakis 4y ago
You're translating the class-based way of working in React against hooks, without stopping to consider understanding hooks as a first-class principle instead of a translation.
It's called useEffect because it runs on the (side)effects observed by the dependency array. An empty array happens to happen on mount. useEffect returns a teardown function which happens to correlate with unmount when an empty array is passed.
It's called useRef because it returns a (mutable) reference that's detached from the reactive layer. The DOM element connection is just sugar.
I agree that useEffect has a lot of footguns, but this position seems very shallow. The whole pattern changed, it doesn't make a lot of sense to continue comparing the two
- pcthrowaway 4y ago> useEffect returns a teardown function which happens to correlate with unmount when an empty array is passed. I believe this teardown function runs on unmount whether or not the dependency array is empty.
- NTARelix 4y agoThis is correct, but I think the point nickdandakis was trying to make is that useEffect does not directly correlate with componentDidUnmount because useEffect's returned callback could be called in the middle of the component's lifecycle, not only when the component unmounts.
- pcthrowaway 4y agoErr.. no, you pass a callback (let's call it the effect callback) that returns a callback (the cleanup callback) to useEffect. The effect callback gets called when the component mounts, and when dependencies (if any) change. The cleanup callback gets called when the dependency unmounts (and will not be called at other times in the lifecycle) edit: I'm wrong, the cleanup is also called when dependencies change, just not on mount.. eg. it gets called before the effect callback being called again. In other words, the cleanup function is called on unmount when useEffect is called with an empty array, and if useEffect has dependencies, it will also be called when those dependencies change
- knodi123 4y agoYes, you're correct, and he got it wrong when talking about it. This kind of goes towards my point. useEffect works, and it works great. It's flexible and powerful - but it's cryptic as hell, and the interface is just "memorize it because you have to", not something more intuitive. What if useEffect required a 2nd argument, but you had the option to pass in self, which would still offer the onMount behavior, by mirroring the way the other form of it worked? Bada-bing, now there's no exception to the rule. What if the 2nd argument was a named argument, like "trigger"? Now it's self-documenting. What if the teardown function as an optional 3rd argument with a name, too? Now it's easy to glance at a useEffect and tell whether it's declaring a teardown without carefully reading the body. etc etc. He says "useRef offering a connection to DOM elements is just sugar", but that's not sweet, to me. There's no reason one thing should do two totally different things. That's exactly what I'm complaining about.
- dceddia 4y agoOh hey, that's me! :wave: I definitely agree useEffect is awfully cryptic and easy to get wrong, and I'm happy to be corrected... but I'm not sure how I'm wrong about it running on every render when there's no 2nd argument? I kinda wish they'd made it easier to do the common operations like onMount and onUnmount by providing some simplified wrappers around useEffect (with less power comes less responsibility... or something). Of course we can make custom hooks for those, but having the well-trodden paths be paved is always nice.
- pcthrowaway 4y agoI misunderstood what you were saying about it running on unmount when the dependency array is empty. Of course, it does run on unmount when the dependency array is empty, and it runs on unmount when there are dependencies in the dependency array. But upon re-reading what you said, I think your intent was that it's comparable to componentWillUnmount() in class-based React only when the dependency array is empty (because otherwise the cleanup function also gets called when dependencies change). My apologies, as I never really used class-based React, so the distinction was lost on me (and also forgot about the cleanup function being called between useEffect callback calls)
- v0idzer0 4y agoIt does, but it runs on more than just unmount when the dependency array is not empty. It runs anytime any dependency in the array changes. This is an important distinction. For example, event listeners added in useEffect will be removed anytime a dependency changes. Then a re-render will occur and they will be added back in the next useEffect body execution. This differs from componentDidUnmount which obviously only runs on unmount and never in the render cycle