我在这里做错了内存泄漏



我有这段代码,它调用一个ajx请求并设置一个错误,如果返回2。它返回2;但没有错误消息显示,并进入下一页(好像是成功)

isCodeExists(userInput).then(res => {
console.log(res);
if (res == 2) console.log("it is 2!!");
// Any other logic that needs the value of `res` should come here...
setErrorMessage('Paper Form ID must begin with "HBCD".');
setHasError(true);
return false;
});

控制台显示:react_devtools_backend.js:4026警告:无法在卸载的组件上执行React状态更新。这是一个无操作,但它表明应用程序中存在内存泄漏。要修复、取消useEffect清理函数中的所有订阅和异步任务。在PaperFormPage

完整的PaperForm页面代码

import React, { useState, useEffect } from 'react';
import TextboxScannerElement from './TextboxScannerElement';
export default function PaperFormPage(props) {
const [pageUserInput, setPageUserInput] = useState([]);
const [hasError, setHasError] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
useEffect(() => {
if (props.pageData !== undefined) {
setPageUserInput([...props.pageData]);
}
}, [props.pageData]);
// element = TextboxElement name
function onUserInput(element, value) {
setErrorMessage('');
setHasError(false);
if (typeof element === 'string') {
let pageUserInputCopy = [...pageUserInput];
let index = pageUserInputCopy.findIndex((obj) => obj.key === element);
let itemCopy = { ...pageUserInputCopy[index] };
itemCopy['userInput'] = value;
pageUserInputCopy[index] = itemCopy;
setPageUserInput(pageUserInputCopy);
}
}
function isCodeExists(userInput) {
setErrorMessage('');
setHasError(false);
let code = encodeURIComponent(userInput);
const testURL =
loris.BaseURL +
'/biosample/ajax/validateScannableCode.php' +
'?scannable_code=' +
code;
return fetch(
testURL,
{
credentials: 'include',
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then((responseData) => {
if(responseData==2) {
return 2;
}
else{
return 1;
}
})
.catch(error => console.warn(error));;
}
function isValid(userInput) {
if (!/^[a-zA-Z0-9]+$/.test(userInput)) {
setErrorMessage('Cannot contain non-alphanumeric characters.');
setHasError(true);
return false;
}
if (!/^.{10,}$/.test(userInput)) {
setErrorMessage('Must be at least 10 characters in length.');
setHasError(true);
return false;
}
if (!userInput.startsWith('HBCD')) {
setErrorMessage('Paper Form ID must begin with "HBCD".');
setHasError(true);
return false;
}
isCodeExists(userInput).then(res => {
console.log(res);
if (res == 2) console.log("it is 2!!");
// Any other logic that needs the value of `res` should come here...
setErrorMessage('Paper Form ID must begin with "HBCD".');
setHasError(true);
return false;
});
return true;
}
function handleSubmit(e) {
if (isValid(pageUserInput[0].userInput)) {
props.updatePageData(pageUserInput);
props.nextStep();
}
}
const form =
pageUserInput.length === 0 ? null : (
<TextboxScannerElement
keyStr={pageUserInput[0].key}
label={pageUserInput[0].label}
name={pageUserInput[0].key}
onUserInput={onUserInput}
value={pageUserInput[0].userInput}
errorMessage={errorMessage}
/>
);
return (
<>
<div className="instructions">
<strong>Instructions:</strong>
<p>Scan the Paper Form found in the kit.</p>
</div>
<FormElement
className="FormElement"
name="form"
fileUpload={false}
onSubmit={handleSubmit}
onUserInput={onUserInput}
>
{form}
<ButtonElement label="Next" onUserInput={onUserInput} />
</FormElement>
</>
);
}

问题是与你isValid函数。

此函数使用async代码,但不等待。

then中的代码发生时,组件已经卸载。

function isValid(userInput) {
// ...
isCodeExists(userInput).then(res => {
if (res == 2) console.log("it is 2!!");
setErrorMessage('Paper Form ID must begin with "HBCD".');
setHasError(true);
// this return doesn't return from `isValid` it returns from the inline function you just created
return false;
});
// the next line always returns true as you never await from the promise above
return true;
}

为了解决这个问题,将函数标记为async并使用' await.

async function isValid(userInput) {
// ...
const response = await isCodeExists(userInput)
if (res == 2) {
setErrorMessage('Paper Form ID must begin with "HBCD".');
setHasError(true);
return false;
}
return true;
}

用法:

async function handleSubmit(e) {
if (await isValid(pageUserInput[0].userInput)) {
props.updatePageData(pageUserInput);
props.nextStep();
}
}

另外,你命名你命名你的函数isValid,这将表明它没有设置任何东西,只是检查是否有什么是有效的,但你设置内部状态。

最新更新