nosco / hx

A simple, easy to use library for React development in ClojureScript.
MIT License
247 stars 16 forks source link

Enforcing "Rules of Hooks" #34

Closed lilactown closed 4 years ago

lilactown commented 5 years ago

Per the React docs:

Only Call Hooks at the Top Level

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls. (If you’re curious, we’ll explain this in depth below.)

Only Call Hooks from React Functions

Don’t call Hooks from regular JavaScript functions. Instead, you can:

✅ Call Hooks from React function components. ✅ Call Hooks from custom Hooks (we’ll learn about them on the next page). By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.

The React team has released an eslint plugin that helps enforce these rules.

I think it would be interesting to see how we could help CLJS developers follow these same conventions.

Here are some considerations:

My initial thought was a hooks macro that was similar to let, but to enforce that hooks can't be used outside of that macro, detect if hooks are being used in loops, etc.

We could do some silly things, like:

Perhaps having it be purely syntax level would be best: e.g. it looks for either <- or use at the beginning of the symbol name, then enforces the top-level rules of hooks.

I'm not sure how we would enforce that Hooks must only be used in React component functions or custom Hooks in this case.

Posting this issue here to collect thoughts!

tomconnors commented 5 years ago

As a potential user of this lib, I like the purely syntax-based option the most. hx.react/fnc* could walk the body and warn if symbols beginning with use or <- are used in disallowed contexts. Might be hard to enumerate the allowed vs disallowed contexts though.

Off topic and feel free to disregard entirely, but I don't find that <- is an improvement over use. "<-" doesn't obviously translate to "use" - without looking at docs I would think it means something closer to "take", and use has the advantage that it's what react already uses.

lilactown commented 5 years ago

That’s good feedback. I liked the look of <- at the beginning because it made the syntax stand out, and also was similar to a syntax someone proposed somewhere (can’t find it rn) that was like:

function MyComponent(props) {
  let counter << state(0);

  ...
}

I do think that there could be some sort of syntax that is more evocative of what Hooks do - hooking into the component’s render cycle and doing some sort of side effect - but the drawbacks of using <- in the function name is starting to grate. For instance, they show up as garbage in React DevTools.

I guess that begs the question: what should we use as the standard? Should we do camel case useXyzAbc? Or kebab-case use-xyz-abc? I’m kind of leaning towards keeping the React idiom in general. Hmm.

DjebbZ commented 5 years ago

My 2 cents: the closer to React the better. In naming it makes no sense to differentiate, doesn't bring any advantage.

On Sat, Apr 13, 2019, 7:32 PM Will notifications@github.com wrote:

That’s good feedback. I liked the look of <- at the beginning because it made the syntax stand out, and also was similar to a syntax someone proposed somewhere (can’t find it rn) that was like:

function MyComponent(props) {

let counter << state(0);

...

}

I do think that there could be some sort of syntax that is more evocative of what Hooks do - hooking into the component’s render cycle and doing some sort of side effect - but the drawbacks of using <- in the function name is starting to grate. For instance, they show up as garbage in React DevTools.

I guess that begs the question: what should we use as the standard? Should we do camel case useXyzAbc? Or kebab-case use-xyz-abc? I’m kind of leaning towards keeping the React idiom in general. Hmm.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Lokeh/hx/issues/34#issuecomment-482847170, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEt3rFlqUmYA-76Xf4uVPnxTTjEJL2Mks5vghSZgaJpZM4bnZ6G .