reactjs - useEffect 之外的 Rect 异步调用 - 内存泄漏
问题描述
我有一个简单的useEffect
钩子Task
:
const TaskAD = ({ match }: TaskADProps) => {
const { taskName } = match.params;
const [task, setTask] = useState<TaskData | null>(null);
const [loading, setLoading] = useState(true);
const authCommunicator = authRequest();
useEffect(() => {
const getTask = async () => {
const taskData = await authCommunicator
.get(`/task/${taskName}`)
.then((response) => response.data);
setTask(taskData);
setLoading(false);
};
getTask();
}, []);
if (loading || task == null) {
return <Spinner centered />;
}
const updateDescription = async (content: string): Promise<boolean> => {
const r = await authCommunicator
.patch(`/task/${task.name}/`, {
description: content,
})
.then((response) => {
console.log("Setting Task data!");
setTask(response.data);
return true;
})
.catch(() => false);
return r;
};
return (
<ProjectEntity name={taskName}>
<Space direction="vertical" size="small" style={{ width: "100%" }}>
<StatusRow status="Open" />
<TaskDetails task={task} />
<Description content={task.description} onSubmit={updateDescription} />
<Title level={2}>Subtasks:</Title>
<Table dataSource={dataSource} columns={columns} />
</Space>
</ProjectEntity>
);
};
Task
对象包含描述。描述是另一个带有文本区域的组件。思路是:当用户更改子组件中的描述时,子组件有一个函数(通过 props 传递)来更新描述。
所以我通过道具传递updateDescription
给我的子组件( )。Description
两者useEffect
和updateDescription
都在我Task
的组件中,该Description
组件基本上是无状态的。怎么了:
- 用户更新描述
- 子组件调用该函数,它会更新我的数据库中的一条记录
- 它从 API 获取响应并调用
setTask
task
变量通过'sDescription
中的 props传递给,因此它们都得到更新,因为 parent 的状态已更改Task
render
Task
- 我看到更新的描述
唯一的问题是,虽然它可以工作,但是当我这样做时,我可以在控制台中看到:
Setting Task data!
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.
(我添加了console.log
只是为了看看它何时发生)。
所以我想问一下,这是否是我在外部进行异步调用的问题,useEffect
还是其他原因?
@EditDescription
代码(我删除了所有不必要的垃圾):
interface DescriptionProps {
content: string;
onSubmit?: (content: string) => Promise<boolean>;
title?: string;
rows?: number;
}
const Description = (props: DescriptionProps) => {
const { content, onSubmit, title, rows } = props;
const [descriptionContent, setDescriptionContent] = useState(content);
const [expanded, setExpanded] = useState(true);
const [editMode, setEditMode] = useState(false);
const [descriptionChanged, setDescriptionChanged] = useState(false);
const editable = onSubmit !== undefined;
const resetDescription = () => {
setDescriptionContent(content);
setDescriptionChanged(false);
};
const changeDescription = (value: string) => {
setDescriptionContent(value);
setDescriptionChanged(true);
};
const descriptionTitle = (
<>
<S.DescriptionTitle>{title}</S.DescriptionTitle>
</>
);
return (
<Collapse
defaultActiveKey={["desc"]}
expandIcon={S.ExpandIcon}
onChange={() => setExpanded(!expanded)}
>
<S.DescriptionHeader header={descriptionTitle} key="desc">
<S.DescriptionContent
onChange={(event): void => changeDescription(event.target.value)}
/>
{descriptionChanged && onSubmit !== undefined ? (
<S.DescriptionEditActions>
<Space size="middle">
<S.SaveIcon
onClick={async () => {
setDescriptionChanged(!(await onSubmit(descriptionContent)));
}}
/>
<S.CancelIcon onClick={() => resetDescription()} />
</Space>
</S.DescriptionEditActions>
) : null}
</S.DescriptionHeader>
</Collapse>
);
};
@Edit2
有趣的是,将其添加到我Description
的解决方案中:
useEffect(
() => () => {
setDescriptionContent("");
},
[content]
);
谁能解释为什么?
解决方案
推荐阅读
- c# - 通过 .NET API 在 Podio 中切换隐藏字段
- python - 如果网站不存在,如何仍然获得输出。(如何处理错误 404)
- python - 如何将 pd.DataFrame 对象的查询方法与标签中带有“-”连字符的列一起使用?
- routing - Yii2 路由仅带获取参数(隐藏控制器和动作)
- java - 使用 Kerberos 身份验证一段时间后,Kafka 消费者停止消费
- r - 按列减去值,值翻转
- python - 如何考虑 txt 文件中的 x 值来绘制阶跃函数图
- sql - ORACLE - 未找到子记录
- java - 如何使用 Java 连接到 FoxPro 数据库而不付费?
- visual-studio-code - 如何在列表栏中列出打开的编辑器