javascript - 我不断收到 Can't perform a React state update on an unmounted component
问题描述
我的两个 React 组件不断收到此错误,但我无法弄清楚。我刚开始学习使用钩子,但似乎无法修复此错误消息。
我尝试在线搜索并通过一些建议的方法,但它似乎对我不起作用。
我在下面看到一篇文章说要添加此代码,但它根本没有效果。
let mounted = true
return function cleanup() {
mounted = false
}
这是两个错误:
“index.js:1 警告:无法在未安装的组件上执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 中的所有订阅和异步任务清理功能。在 BoardAdmin(在 App.js:125)中的组件(在 PrivateRoute.js:9)“
“警告:无法对未安装的组件执行 React 状态更新。这是一个无操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。在 SFTPList (at CsvExtractor.js:206) in div (由 Col 创建) in Col (at CsvExtractor.js:205) in div (由 Row 创建) in Row (at CsvExtractor.js:183) in form (由 Form 创建) in表单(在 CsvExtractor.js:129)在 CsvExtractor(在 BoardAdmin.js:30)中的标题(在 BoardAdmin.js:29)在 div(在 BoardAdmin.js:28)在 BoardAdmin(在 App.js:125)中组件(在 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 如下
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;
解决方案
如果用下面的代码修复它
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();
};
}, []);
推荐阅读
- docker - 如何获取正在运行的 docker 容器的所有端点/REST 路径(404 错误)
- lightningchart - 是否可以在 JS API 中创建瀑布系列 3D 图表?
- python - Python对列表进行排序和切片并保存为新列表
- android - 我如何在一行 Flutter 中获取所有按钮?
- flutter - 如何从我的电脑中挑选视频来颤动网络应用程序?
- node.js - typeError: fs/promises read is not a function
- sql-server - SqlDataReader.GetValue 对几何列不成功
- recaptcha - ReCAPTCHA 限制 IP 地址
- c++ - 使用 KlocWork 自定义检查器报告可能返回失败代码的 COM API 调用
- reactjs - Spring boot 和 React js 中的 CORS 错误策略