My conditional beef: in my app, users can choose between using the built-in mic for speech recognition or a 3rd party service (LiveKit). If the user chooses the built-in mic, I still must allocate memory for LiveKit's services because it's exposed as a hook, even if the user will never use it. This problem compounds - every option that I expose that uses a hook requires that I allocate memory for an option that may never be used. Also TTS - users can choose to use the phone's TTS, or a remote service, etc. Every option I offer, if the library exposes it as a hook (and they virtually always do), if I naively implement the feature, allocates memory for a hook that might never be used.
Fuck. React. Hooks.
My workaround is to conditionally render empty fragments. These fragments wrap hooks, which I then inject into the context. This makes it so I can conditionally run hooks. This is why I complained that React can handle conditional components, but not hooks. Concretely: https://pastebin.com/sjc3vXTd I'm using Zustand because god I need a lifecycle outside of React.
Y'know how people complain about how Async "colors" functions? Hooks are also a type of function coloring. And they don't compose with Async.
I think you actually can conditionally render a hook but that choice has to last for the entire rendered lifetime of the component. But that doesn't really help you when your user can switch between them.
All the oddness about hooks fall out of that implementation. They can only be used inside components because they rely on component state management, and having to be called at the top level is a simplification of "hooks must always be called in the same order the same number of times" (no conditionals or loops) because otherwise the setState index gets messed up and you're getting the wrong state back when it's called.
Just because you're in React land doesn't mean you can't still write regular old js/ts and hook in only when you need it. I imagine you'd do something quite similar in any other framework.
Some libs do not expose "vanilla" js/ts functions that I can call - e.g. `LiveKitRoom` https://github.com/livekit/client-sdk-react-native
It only takes 1 hook to pollute your entire factory pattern; the comparison to colored async functions wasn't spurious. Hook-only options seem especially prevalent in the React Native ecosystem (ironically, given the memory constraints of phones).
Of course, I could fork/go down to the native layer, but this just proves my point that React DX is hot garbage.
There are only two rules:
1. Only call Hooks at the top level
2. Only call Hooks from React functions
Per https://react.dev/reference/rules/rules-of-hooks
Not sure I understand the conditional beef, perhaps you can give example? I would assume if you want `if condition, useEffect(...)` you could simply replace with `useEffect(() => if condition...)`, no?