4 ms·
> Ahh, this is such a pet peeve of mine. I hate how it leaks. A thing I often also encounter in this vein is when you write a useEffect, but the linter forces y
by p1necone 1y ago
> Ahh, this is such a pet peeve of mine. I hate how it leaks. A thing I often also encounter in this vein is when you write a useEffect, but the linter forces you to declare everything in the dependency array. I only want the effect to trigger when x changes, and then call function y. But I have to declare y as well, but then if y isn't memoed it will trigger every render. But I don't want that, and I might not even have full control of function y, coming from somewhere else. I could usecallback around it myself first, but that just moves the problem, as I need to maintain the correct closure, or there will be subtle bugs.
If y never changes it should be declared as a const function outside of the context of the component, then it can be safely included in the dependency array without triggering unnecessary rerenders.
If y does change, you've just created a bug where your component will keep using an old version of y.
- matsemann 1y agoYup, but that's the problem. I don't know, and I don't care, I just want to run my effect when x changes. But I can't, the details of y's implementation must leak.
- PaulHoule 1y agoOften I don't want to run effects, I just want everything calculated properly and then have my components render. I see useEffect() as a bad smell and keep score by how few of them I use (like golf) There really are cases you need it, but people often use them to move state around when they are keeping state in the wrong place.
- skydhash 1y agouseEffect should be used only when you want to bring something from outside the React tree which is not constant compared to the tree lifetime (anything that's not part of the UI module), hooking it to the tree lifecycle. useRef is for when you don't care the external thing's mutation. Any other hooks should be used when deriving from things that is already present in the React tree (props, local state, or other memoized variables)
- skydhash 1y agoMust it? React is a closed ecosystem. Anything that enters either do through the root component or through hooks (in the functional version). If both x and y enters the ecosystem, they must adapt to the rules, meaning you write what happens when they change. Because the only reason for them to enter is that they are not constant outside React's world (which is the ultimate truth). If they are constant, then just use the reference directly.
- matsemann 1y agoYes, but then you have to do as the author says: wrap every single function in a use callback and declare it dependencies. Otherwise it's unsafe to use for others. Which to me is a broken design. And y in my case may not be my function, either from a library or somewhere else in the application I don't want to modify just because my usage needs it. It should be a compiler thing, not up to the devs, the abstraction feels off.
- p1necone 1y agoI think you've got this backwards. If you write a React component that internally uses some 3rd party component/hook, and on every render of your component you pass something as a prop to that 3rd party component that's different from the previous render you should expect that 3rd party component/hook to also rerender/rerun. This isn't really surprising, nor is it even a problem in most cases. If you're the one writing that reusable thing, you don't need to do anything special or write the kind of defensive code you're talking about. It's up to the original source of those props to make sure they're not creating new objects every render if they're in a context where that even matters
- matsemann 1y agoI don't mean I'm passing new stuff to the 3rd party hook, but that it returns a function that's usecallbacked, and hence I cannot myself use it as a dependency in a useEffect without it triggering every render. So yeah, if you expose a function in a piece of reusable code, you must useCallback around everything and be very defensive, or you mess up for those integrating with you.
- deleted 1y ago[deleted]
- agos 1y agoy might be "changing" but being effectively the same function or the same array. There are legitimate cases when you want to just read the latest value of something inside an effect without it being a dependency, and after years of gaslighting about it React seems to agree and useEffectEvent is coming.