【发布时间】:2021-03-25 23:09:12
【问题描述】:
我的两个 React 组件不断收到此错误,但我无法弄清楚。我刚开始学习使用钩子,但似乎无法修复此错误消息。
我尝试在线搜索并尝试了一些建议的方法,但它似乎对我不起作用。
我看到一篇文章说在下面添加这段代码,但它根本没有效果。
let mounted = true
return function cleanup() {
mounted = false
}
这是两个错误:
-
"index.js:1 警告:无法在未安装的组件上执行 React 状态更新。这是一个无操作,但它表明您的应用程序中存在内存泄漏。要修复,取消所有订阅和异步任务在 useEffect 清理函数中。 在 BoardAdmin 中(在 App.js:125) 在组件中(在 PrivateRoute.js:9)”
-
“警告:无法在未安装的组件上执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请在 useEffect 清理函数中取消所有订阅和异步任务. 在 SFTPList 中(在 CsvExtractor.js:206) 在 div 中(由 Col 创建) 在 Col (在 CsvExtractor.js:205) 在 div 中(由 Row 创建) 在行中(在 CsvExtractor.js:183) 在表单中(由表单创建) 形式(在 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;
【问题讨论】:
-
错误从哪里抛出?
-
我在原始帖子中添加了两个错误,抱歉我应该从一开始就添加它们。
-
好吧,您在
useEffect中有一个promise,您在其中设置了状态setContent(..);,但是当组件卸载然后promise 解析时会发生什么?这就是错误的来源。 -
此外,您应该创建一个可重现的最小示例,而不是粘贴整个代码,请参阅How to create a Minimal, Reproducible Example
标签: javascript node.js reactjs axios react-hooks