简体   繁体   中英

I keep getting Can't perform a React state update on an unmounted component

I keep getting this error for two of my React components and i can't figure it out. I just started to learn to use hooks and I can't seem to fix this error message.

I tried searching online and going through a few suggested methods but it doesn't seem to work for me.

I saw an article saying to add this code below but it has no effect at all.

let mounted = true

return function cleanup() {
            mounted = false
        }

Here's the two errors:

  1. "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 a useEffect cleanup function. in BoardAdmin (at App.js:125) in component (at PrivateRoute.js:9)"

  2. "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 SFTPList (at CsvExtractor.js:206) in div (created by Col) in Col (at CsvExtractor.js:205) in div (created by Row) in Row (at CsvExtractor.js:183) in form (created by Form) in Form (at CsvExtractor.js:129) in CsvExtractor (at BoardAdmin.js:30) in header (at BoardAdmin.js:29) in div (at BoardAdmin.js:28) in BoardAdmin (at App.js:125) in component (at PrivateRoute.js:9)"

csvextractor.js

import React, { useState, useEffect, useRef } from 'react';
import Dropzone from 'react-dropzone';
import MultiSelect from 'react-multiple-select-dropdown-lite';
import 'react-multiple-select-dropdown-lite/dist/index.css';
import 'react-datepicker/dist/react-datepicker.css';
import DatePicker from 'react-datepicker';
import SFTPList from './SFTPDownload';
import { Form, Row, Col, Button } from 'react-bootstrap';
import FileService from '../services/file.service';

import { history } from '../helpers/history';

const CsvExtractor = () => {
  const [file, setFile] = useState(null); // state for storing actual file
  const [details, setDetails] = useState({
    title: '',
    description: '',
  });
  const [errorMsg, setErrorMsg] = useState('');
  const dropRef = useRef(); // React ref for managing the hover state of droppable area
  const [startDate, setStartDate] = useState(new Date());
  const [endDate, setEndDate] = useState(null);
  const [filters, setFilters] = useState([]);

  const filterOptions = [
    {
      value: 'translate',
      label: 'Translate to EN',
    },
    {
      value: 'emailentrant',
      label: 'Email Entrant',
    },
    {
      value: 'emailsortant',
      label: 'Email Sortant',
    },
    {
      value: 'appelentrant',
      label: 'Appel Entrant',
    },
    {
      value: 'appelsortant',
      label: 'Appel Sortrant',
    },
    {
      value: 'chat',
      label: 'Chat',
    },
  ];

  const handleSelect = (selections) => {
    setDetails({
      ...details,
      description: `${selections}`,
    });
    setFilters(selections.split(','));
  };

  const handleInputChange = (event) => {
    setDetails({
      ...details,
      [event.target.name]: event.target.value,
    });
  };

  const onDrop = (files) => {
    const [uploadedFile] = files;
    setFile(uploadedFile);

    const fileReader = new FileReader();
    fileReader.onload = () => {};
    fileReader.readAsDataURL(uploadedFile);
    dropRef.current.style.border = '2px dashed #e9ebeb';
  };

  const onChange = (dates) => {
    const [start, end] = dates;
    const tdate = end === null ? '' : end.toString().slice(4, 15);
    setDetails({
      ...details,
      title: `${start.toString().slice(4, 15)} - ${tdate}`,
    });
    setStartDate(start);
    setEndDate(end);
  };

  const updateBorder = (dragState) => {
    if (dragState === 'over') {
      dropRef.current.style.border = '2px solid #000';
    } else if (dragState === 'leave') {
      dropRef.current.style.border = '2px dashed #e9ebeb';
    }
  };

  const handleOnSubmit = async (event) => {
    event.preventDefault();

    try {
      const { title, description } = details;

      if (title.trim() !== '' && description.trim() !== '') {
        if (file) {
          const formData = new FormData();
          formData.append('startDate', startDate);
          formData.append('endDate', endDate);
          formData.append('filters', filters);
          formData.append('file', file);
          formData.append('title', title);
          formData.append('description', description);

          setErrorMsg('');

          await FileService.uploadFile(formData);
          history.push('/list');
        } else {
          setErrorMsg('Please select a file to add.');
        }
      } else {
        setErrorMsg('Please enter all the field values.');
      }
    } catch (error) {
      error.response && setErrorMsg(error.response.data);
    }
  };

  return (
    <React.Fragment>
      <Form className="search-form">
        {errorMsg && <p className="errorMsg">{errorMsg}</p>}
        <Row>
          <Col>
            <Form.Group controlId="title">
              <Form.Control
                type="text"
                name="title"
                value={details.title || ''}
                placeholder="Enter title"
                onChange={handleInputChange}
              />
            </Form.Group>
          </Col>
        </Row>
        <Row>
          <Col>
            <Form.Group controlId="description">
              <Form.Control
                type="text"
                name="description"
                value={details.description || ''}
                placeholder="Enter description"
                onChange={handleInputChange}
              />
            </Form.Group>
          </Col>
        </Row>
        <Row>
          <Col>
            <div>
              <h5>Select date range</h5>
            </div>
            <DatePicker
              selected={startDate}
              onChange={onChange}
              startDate={startDate}
              endDate={endDate}
              selectsRange
              inline
            />
          </Col>

          <Col>
            <h5>Select filters (at least one)</h5>

            <MultiSelect
              style={{ backgroundColor: 'white', marginTop: '10px' }}
              onChange={handleSelect}
              options={filterOptions}
            />
          </Col>
        </Row>

        <Row>
          <Col xs={12}>
            {/* <div className="upload-section"> */}
            <Dropzone
              onDrop={onDrop}
              onDragEnter={() => updateBorder('over')}
              onDragLeave={() => updateBorder('leave')}
            >
              {({ getRootProps, getInputProps }) => (
                <div {...getRootProps({ className: 'drop-zone' })} ref={dropRef}>
                  <input {...getInputProps()} />
                  <p>Drag and drop a file OR click here to select a file</p>
                  {file && (
                    <div>
                      <strong>Selected file:</strong> {file.name}
                    </div>
                  )}
                </div>
              )}
            </Dropzone>
            {/* </div> */}
          </Col>
          <Col>
            <SFTPList />
          </Col>
        </Row>
        <Button variant="primary" type="submit" onClick={handleOnSubmit}>
          Submit
        </Button>
      </Form>
    </React.Fragment>
  );
};

export default CsvExtractor;

adminboard.js is below

import React, { useState, useEffect, useRef } from 'react';
import 'react-multiple-select-dropdown-lite/dist/index.css';
import 'react-datepicker/dist/react-datepicker.css';

import UserService from '../services/user.service';
import CsvExtractor from './CsvExtractor';

const BoardAdmin = () => {
  const [content, setContent] = useState('');

  useEffect(() => {
    UserService.getAdminBoard().then(
      (response) => {
        setContent(response.data);
      },
      (error) => {
        const _content =
          (error.response && error.response.data && error.response.data.message) ||
          error.message ||
          error.toString();

        setContent(_content);
      },
    );
  }, []);

  return (
    <div className="container">
      <header className="jumbotron">
        <CsvExtractor />
      </header>
    </div>
  );
};

export default BoardAdmin;

If fixed it with the code below

  const [filesList, setFilesList] = useState([]);
  const [errorMsg, setErrorMsg] = useState('');

  useEffect(() => {
    const source = axios.CancelToken.source();
    const getFilesList = async () => {
      try {
        const { data } = await axios.get('api/file/getallfiles/', {
          headers: authHeader(),
          cancelToken: source.token,
        });
        setErrorMsg('');
        setFilesList(data);
      } catch (error) {
        if (axios.isCancel(error)) {
        } else {
          error.response && setErrorMsg(error.response.data);
        }
      }
    };
    getFilesList();
    return () => {
      source.cancel();
    };
  }, []);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM