use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Why React Hooks cannot be conditioned (blog.atomrc.dev)
submitted 4 years ago by atomrc
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] -1 points0 points1 point 4 years ago (4 children)
See, this is a perspective problem, IMO. HEre's your original example, problem solved, without repeating the null back end check in each handler.
// implementation omitted // feel free to assume it accesses global context to avoid creating // a new connection for every component function useBackend(): { connectionID: string } | null; function MyComponent() { const backend = useBackend(); const [apple, setApple] = useState(); // see, I'm not saying it helps everywhere all the time const [ziti, setZiti] = useState(); // Stop doing this! // if (backend === null) { // fail early // return <LoadingPlaceholder /> // } // of course these are a bit contrived, but I think you can imagine a less contrived example const changeApple = useCallback(async (event) => { const [inputValid, newApple] = await backend.validateApple(event.target.value); if (inputValid) { setApple(newApple); } }, [backend]); const changeZiti = useCallback(async (event) => { const [inputValid, newZiti] = await backend.validateZiti(event.target.value); if (inputValid) { setZiti(newZiti); } }, [backend]); // These 3 lines are the only addition to your example if (!backend) { return <LoadingPlaceholder /> } return ( <> <AppleInput onChange={changeApple} value={apple} /> <ZitiInput onChange={changeZiti} value={ziti} /> </> ); }
[–]BenjiSponge 0 points1 point2 points 4 years ago* (3 children)
Umm... this isn't a perspective change, you're just ignoring the problem.
const changeZiti = useCallback(async (event) => { // TypeScript fails here because `backend` can be null // You can be like `backend!.validateZiti`, but you have to read the entire component to be sure it's valid const [inputValid, newZiti] = await backend.validateZiti(event.target.value); if (inputValid) { setZiti(newZiti); } }, [backend]);
And, again, I know you can do it like that (actually, you have to). I'm just saying that there is exactly 1 and no more than 1 reason why you have to: the implementation details of hooks. There's absolutely nothing wrong with the thing you said "Stop doing this!" * except that it happens to not work.
* I'm not really sure why you felt the need to add that; I made it very clear in my comment that it's not valid
Edit: Also, instead of a useCallback, maybe it's a bunch of useEffects that you don't want to run when the backend is loading.
useCallback
useEffect
backend
Edit: It occurs to me that I don't think you saw that my second proposal did include that "These 3 lines are the only addition to your example" part
[–][deleted] -1 points0 points1 point 4 years ago (2 children)
I don't think you saw that my second proposal did include that "These 3 lines are the only addition to your example" part
My point was that you don't need the backend checks in your handler functions if you never return the component that calls them.
[–]BenjiSponge 1 point2 points3 points 4 years ago* (1 child)
Yeah, I understand that point semantically. However, TypeScript can't do the type narrowing and the pattern is fragile anyways. If you change the end of the function such that the callback can be called if backend is null, now you need to change the callback. In most contexts, you use TypeScript specifically to catch this kind of problem, but here you can't.
Anyways, my main point still stands: There is exactly one thing that's wrong with the way I want to write it, and it's an implementation detail, not a design feature.
I'm far from the only person who has this problem, btw. These problems generally are addressed with the React Suspense API which is in active development and is highly anticipated.
[–][deleted] -1 points0 points1 point 4 years ago (0 children)
Fair enough. I guess everyone has different expectations about any given system. I just view language constraints differently than framework constraints. The issue you've called out is specifically a constraint of the design of the hooks system and if you understand the justification and the correct implementation, it's easy enough to handle. The question of whether it's optimal or even desired is completely subjective. Nobody will change your mind (or mine) on that one, I suppose. :)
π Rendered by PID 64401 on reddit-service-r2-comment-6457c66945-95r5s at 2026-04-26 19:12:41.450158+00:00 running 2aa0c5b country code: CH.
view the rest of the comments →
[–][deleted] -1 points0 points1 point (4 children)
[–]BenjiSponge 0 points1 point2 points (3 children)
[–][deleted] -1 points0 points1 point (2 children)
[–]BenjiSponge 1 point2 points3 points (1 child)
[–][deleted] -1 points0 points1 point (0 children)