I have a Provider component which passes down some data through its props, which will later be used across the app.
It looks something like this:
export const MyContext = createContext({});
MyContext.displayName = 'My Context';
export const MyProvider = ({ children }) => {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
const setData = async () => {
setLoading(true);
setItems(await getItemsApiCall());
setLoading(false);
};
useEffect(() => {
console.warn('component re-rendering')
if (!items.length) {
setData();
}
}, [items]);
return (
<MyContext.Provider value={{items, loading}}>
{children}
</MyContext.Provider>
);
};
In theory this should work fine, however I am seeing a bunch of extra re-renders through the console.warn
which seem unnecessary, also I am getting the warning relating to the state update on an unmounted component
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application...
Although I have seen the solution for this in other threads, none of them work for me because I am not only setting items
, but also loading
, which I need to put in spinners and other such things on other parts of the app while fetching data.
Anyway, is there a way to prevent these re-render before the mount and to surpress the warning under these circumstances?
Edit: For the record, I am currently getting 2 re-renders before the warning relating to updating the state of an unmounted component, and then two other re-renders (those of which are to be expected). So basically, my console look something like this:
component re-rendering
component re-rendering
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application...
component re-rendering
component re-rendering
Edit2: For what it is worth, I would also like to show how the MyProvider
is being used. It is simply wrapping another component in a particular route. Something like this:
const App = () => (
<Router>
<Switch>
<Route
path='/items'
exact
component={() => (
<MyProvider>
<Items/>
</MyProvider>
)}
/>
</Switch>
</Router>
)
The behaviour I get above happens simply when visiting the /items
route.