React js 18 Bug: eslint-plugin-react-hooks does not allow passing hook as props in jsx syntax
React version: latest
demo:https://codesandbox.io/s/cranky-framework-p7r5vb?file=/src/App.tsx
The current behavior
jsx syntax does not work correctly.
<>
<IsolateRender useRender={() => useCustomeHook()} /> // error !
<IsolateRender {...{ useRender: () => useCustomeHook() }} /> no error!
</>
it shows this error:
React Hook "useCustomeHook" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function. (react-hooks/rules-of-hooks)
The expected behavior
jsx syntax should work as object syntax.
Why would you expect this to be allowed? It is explicitly stated that you can only use hooks in function components or custom hooks
Hey @alisajadih, the documentation explains that we should use hooks only at the top level
Don’t call Hooks inside loops, conditions, or nested functions [...]
The example you sent is using the naming convention that identifies your function as a hook (with use
prefix) but it's not an actual hook. It's pretty much like another react component as it only returns another JSX.
const useCustomeHook = () => {
return <div />;
};
Possible solution
👉🏻 If you rename your useCustomHook
function to be customHook
it would not give you an error anymore.
In this case, it wouldn't give the error because it's not considered a hook.
Hooks' purpose
I guess this question came because the purpose of the hook is a bit confuse for you. I'd check the Introducing Hooks documentation, to make sure you can clarify this point. In summary, hooks are useful to deal with component lifecycle when it is just a simple function rather than a class with inheritance and predefined functions.
From the documentation:
They let you use state and other React features without writing a class [...]
Hooks allow you to reuse stateful logic without changing your component hierarchy [...]
Hooks let you split one component into smaller functions based on what pieces are related [...]
Thanks for your answers. I know rules of hooks and hooks aspects. I want to make an inline custom hook (by passing anonymouse function as
useRender
prop). my problem is when I try try to pass anonymouse function like this:<IsolateRender useRender={() => useCustomeHook()} />
It shows me an error. But when i try to pass it as object:<IsolateRender {...{ useRender: () => useCustomeHook() }} />
It doesn't have any problem.
Also for clarifying the problem, this syntax works correctly as well:const useCostomHook = () => {/*do something*/} <IsolateRender useRender={useCustomeHook} />