I've recently started working on a React project where I came across a provider component that returns a render props callback function. I noticed that there are hooks being used directly inside the callback function, which goes against React's rules. However, the code is currently working fine and not throwing any errors in the console.
Here is an example of the code I'm working with:
import React, { useState, useEffect } from 'react';
const MyProvider = ({ children }) => {
// This provider is doing some api logic etc...
return children({ data, isLoading, isError });
};
const MyComponent = () => {
// Some additional logic...
return (
<MyProvider>
{({ data, isLoading, isError }) => {
// React Hook "useEffect" cannot be called inside a
// callback. React Hooks must be called in a React function
// component or a custom React Hook function.
// eslint(react-hooks/rules-of-hooks)
useEffect(() => {
console.log('This useEffect example is my concern');
}, []);
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error!</div>;
return (
<div>
<p>Data: {JSON.stringify(data, null, 2)}</p>
</div>
);
}}
</MyProvider>
);
};
As you can see, the MyProvider component is using the useEffect hook to do some additional logic inside the callback.
My eslint is flagging this issue as a violation of React's rules but the code is working as intended from what I can see. The only "bug" which I think might be from this, is that the Vite hmr is not working. So whenever I make changes I have to reload the page entirely. Should I be worried about this approach? Are there any potential issues that could arise from declaring hooks directly inside a render props callback function?
I would appreciate any advice or insights on this topic. Thank you!
This is because React needs to keep track of the state and lifecycle of the component, and it can only do so if the hooks are called directly in the component or hook function.
Being said that, you can modify your callback to something like this -
const ExampleComponent = ({ data, isLoading, isError }) => {
useEffect(() => {
console.log('This useEffect example is my concern');
}, []);
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error!</div>;
return (
<div>
<p>Data: {JSON.stringify(data, null, 2)}</p>
</div>
);
}
const MyComponent = () => {
// Some additional logic...
return (
<MyProvider>
{(props) => <ExampleComponent {...props} />}
</MyProvider>
);
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With