I'm currently building an Electron app with React, and I keep getting an error that my state is changing while my component isn't mounted.
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. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. in Start (created by Context.Consumer)
I've looked up multiple threads and questions about this, and there are no async tasks or ways that I can possibly think the state is changing in my Start component, though maybe someone else may see something I don't.
I currently only use state in this component to redirect using react router when a file is dropped into the app. Since the Redirect component needs to be rendered in order for the redirect to occur, I have it set to null in my state and then change it to the component when dropped. This way I can simply just put the state down in my return statement for the component.
Store.js:
import React, { useState } from "react";
import { Redirect } from "react-router-dom";
import drop from "../../assets/images/drop.svg";
import { ipcRenderer } from "electron";
import M from "materialize-css";
const Start = () => {
const [redir, setRedir] = useState(null);
document.ondragover = document.ondrop = (e) => {
e.dataTransfer.dropEffect = "copy";
e.preventDefault();
};
document.ondrop = (e) => {
for (let file of e.dataTransfer.files) {
// notify user about incompatible file types
if (
file.path.split(".").pop() !== "js" &&
file.path.split(".").pop() !== "css" &&
file.path.split(".").pop() !== "html" &&
file.path.split(".").pop() !== "svg"
) {
M.toast({
html: `"${file.path
.split("/")
.pop()}" could not be minified due to incompatible file type.`,
});
} else {
ipcRenderer.send("file:add", file.path);
setRedir(<Redirect to="/list" />);
}
}
e.preventDefault();
};
// display toast for if file contains JSX
ipcRenderer.on("minify:error-react", (e, data) => {
M.toast({
html: `${data.path
.split("/")
.pop()} could not be minified because the file contains JSX.`,
});
});
return (
<div className="start">
<div className="start-drop">
<img src={drop} draggable="false" alt="" />
<p>Drop any HTML, CSS, JS, or SVG files here to minify</p>
</div>
{redir}
</div>
);
};
export default Start;
As for reference, this is the first page the user sees in the application upon opening. No other component (besides the App component) should be rendering before this one since this is simply just a route. Let me know if you need more code for context and I'll add it.