【发布时间】:2021-12-03 15:15:16
【问题描述】:
这个组件有问题。
当我不断调用这个组件时,我收到了一条警告消息。
警告信息如下所示。
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.
我已经使用return方法清除了timerId,但我得到了这个文本。
如何修改这个组件中的useEffect?
我该怎么办?
下面是我的组件
import React, { useState, useEffect } from 'react';
import { Form, List, Button } from 'semantic-ui-react';
import axios from 'axios';
const Search = () => {
const [term, setTerm] = useState('programming')
const [debouncedTerm, setDebouncedTerm] = useState(term);
const [results, setResults] = useState([]);
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedTerm(term);
}, 1000);
return () => {
clearTimeout(timerId);
};
}, [term]);
useEffect(() => {
const search = async () => {
const {data} = await axios.get('https://en.wikipedia.org/w/api.php', {
params: {
action: 'query',
list: 'search',
origin: '*',
format: 'json',
srsearch: debouncedTerm,
},
});
setResults(data.query.search);
};
if(debouncedTerm){
search();
}
}, [debouncedTerm])
const handleClick = (pageid) => {
window.open(`https://en.wikipedia.org?curid=${pageid}`);
}
const renderedResults = results.map((result) => {
return (
<List.Item key={result.pageid}>
<Button floated='right' style={{"margin": "10px"}} onClick={() => handleClick(result.pageid)}>Go</Button>
<List.Content>
<List.Header>{result.title}</List.Header>
{result.snippet}
</List.Content>
</List.Item>
);
});
return (
<React.Fragment>
<Form>
<Form.Field>
<label>Search</label>
<input placeholder='Search Word'
onChange={(e) => setTerm(e.target.value)}
value={term}
/>
</Form.Field>
</Form>
<List celled>
{renderedResults}
</List>
</React.Fragment>
)
}
export default Search;
【问题讨论】:
-
您确定是第一个触发警告的 useEffect 吗?而不是第二个? stackoverflow.com/questions/46110082/…
-
@Erik 警告消息有链接。当我点击它时,它会引导我到第一行代码
const [term, setTerm] = useState('programming')。 -
@Erik 我认为是第二个。我该如何解决?
-
我不确定。您可以尝试在第一个 useEffect (设置 debouncedTerm 的地方)中进行 axios 调用。
-
但是你并没有使用清理函数来实现 get 查询的第二个效果,所以使用 CancelToken 或 AbortController 在卸载时中止请求。
标签: reactjs components