Reputation: 549
There is this section on React Hooks that I don't really understand what it is saying:
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.
What does it mean to only call Hooks from React function components and how is a React function different than what I would call a regular functional component?
In my mind they're the same:
const App = () => {
useEffect(() => //do stuff);
return (
// return some sort of stuff here
)
}
The reason I ask is the eslint I have for hooks is complaining about the way I'm using useState
here:
const checkPermissions = () => { //when I change this to 'usePermissions', it works fine
const [locPermission, setLocPermission] = useState(null); // eslint error here
//'React Hook "useState" is called in function "checkPermissions" which
//is neither a React function component or a custom React Hook function.'
//Check for and set state for permissions here
return locPermission;
};
Upvotes: 7
Views: 3906
Reputation: 1166
What they mean is the entry point for a set of hooks should be within a React component and not elsewhere if it is used as a hook e.g. in this very arbitrary/simple example here:
my-utils/useCustomHook.js
arbitrary custom hook
import { setState } from 'React'
export default function useCustomHook() {
const [state, setState] = useState(()=> 'anyRandomState');
// ...possibly re-using other custom hooks here,
// then returning something for our component to consume
}
MyComponent.js
Your React component
import React, { setState } from 'react'
import useCustomHook from 'my-utils/useCustomHook'
function MyComponent() {
const offDaHook = useCustomHook();
return (
<div>
Hi, I'm your component with a custom hook.
I see that the value returned was {offDaHook}.
</div>
);
}
random-other-business-logic.js
another file which does other things that does not include rendering
import useCustomHook from `my-utils/useCustomHook.js`
useCustomHook(); // Arbitrarily calling from non React component!
// do other things...
One reason ESLint could/would complain is hooks should be formatted as useXXX
e.g. in your case, rather than checkPermissions
, something like usePermissionChecker
(or useCheckPermissions
depending on how you think in code) should get the linter to recognize that this function is a custom hook.
I also agree -- this phrasing could probably be improved -- the custom rules of hooks threw me for a little bit of a loop at first as well. I am not 100% sure why this is the case but this is just what I got from that.
I am not sure if React internally appends other variables to hooks such as counting their instances/prototypes but guessing that if the React team doesn't, they would like to reserve the right to do that going forward. In either case, it is a lot cleaner to separate your React-state code from your non-React business logic and hooks using the useHooks
convention as they are a little bit funky with their nuances.
Definitely something interesting to look into and wish I could tell you more, but this is just from another user-world programmer currently.
Upvotes: 5