How do I avoid "Can't perform a React state update on an unmounted component" error on my application?

Viewed 96

I'm trying to make upload file part and I got an issue like when I upload csv file and the first component has got error and when I upload file on another component it doesn't get error

and the error is like this :

index.js:1 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 the componentWillUnmount method.

my website is working fine, however I'm worrying the error would make it bad

info state is for uploading file .

and i need to upload file each components at Parent component but i'm using it in Child component and it works fine except that error

I assume that info state is making the issue .

I'd like to know how to avoid that error

Thank you in advance

and my code is like this:

Parent Component :

const eachComponent = (index, id) => (
    <DataSide id={id} key={index} onClick={chartItself}>
      <SettingMenu
        panelNum={index + 1}
        show={show[index]}
        chart={chart[index]}
        changeLayout={changeLayout}
      />
      {ChangeableType(index + 1).map(
        (id, idx) =>
          chart[index].key === id.key && ChangeableType(index + 1)[idx]
      )}
      {BarTypes(index).map(
        (id, idx) => chart[index].key === id.key && BarTypes(index)[idx]
      )}
      {/* {LineTypes(index).map(
        (id, idx) => chart[index].key === id.key && LineTypes(index)[idx]
      )}
      {GridTypes(index).map(
        (id, idx) => chart[index].key === id.key && GridTypes(index)[idx]
      )} */}
    </DataSide>
  );

  const layout = [
    eachComponent(0, "first"),

    eachComponent(1, "second"),

    eachComponent(2, "third"),

    eachComponent(3, "fourth"),

and Child component :

const CsvFile = ({ match, location }) => {
  const { panelNum, changeLayout } = location.state;
  const chart = location.data;
  const { Plugins, DataContextUseState } = useContext(DataContextApi);
  const [plugins, setPlugins] = Plugins;
  const [DataContext, setDataContext] = DataContextUseState;

  const [info, setInfo] = useState([]);
   ///this info is the cause as i guess 
  
  
  
  const history = useHistory();

  const [y, setY] = useState();
  const [x, setX] = useState();

  const [title, setTitle] = useState("");

This is the Child component of second one that I'm using info state :

const CsvFileReader = ({ setInfo }) => {
  const handleOnDrop = data => {
    const infos = data.map(item => item.data);
    setTimeout(() => setInfo([...infos]), 1000);
  };

  const handleOnError = (err, file, inputElem, reason) => {
    console.log(err);
  };

  const handleOnRemoveFile = data => {
    console.log(data);
  };

  return (
    <>
      <MainReader>
        <CSVReader
          onDrop={handleOnDrop}
          onError={handleOnError}
          config={
            (({ fastMode: true }, { chunk: "LocalChunkSize" }),
            { header: false })
          }
          addRemoveButton
          onRemoveFile={handleOnRemoveFile}
        >
2 Answers

You are using a timeout to update state, possibly after the component has unmounted. Use a react ref to store a reference to the current timeout and clear it when the component unmounts.

const CsvFileReader = ({ setInfo }) => {
  const timerRef = React.useRef();

  useEffect(() => {
    return () => clearTimeout(timerRef.current); // clear any running timeouts
  }, []);

  const handleOnDrop = data => {
    const infos = data.map(item => item.data);
    timerRef.current = setTimeout(() => setInfo([...infos]), 1000); // save timeout ref
  };

You can use a ref to check component is unmounted or not in CsvFileReader component

const ref = useRef()

const handleOnDrop = data => {
  const infos = data.map(item => item.data);
  setTimeout(() => ref.current && setInfo([...infos]), 1000);
};

return (
  <div ref={ref}>
    <MainReader>
Related