[英]React useEffect warning in MERN App: Can't perform a React state update on an unmounted component
[英]React useEffect Warning Warning: Can't perform a React state update on an unmounted component
我有这个组件的问题。
当我不断调用这个组件时,我收到一条警告消息。
这是警告消息,如下所示。
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.
我已经使用返回方法来清除 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;
试试这个(axios v0.22.0+):
useEffect(() => {
const controller= new AbortController();
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,
},
signal: controller.signal
});
setResults(data.query.search);
};
if(debouncedTerm){
search();
}
return ()=>{
controller.abort();
}
}, [debouncedTerm])
同样的事情,但具有自动清理能力,可以使用我的库( Generic fetch demo )完成:
import { useAsyncEffect } from "use-async-effect2";
import cpAxios from "cp-axios";
// ...
useAsyncEffect(function*(){
if(!debouncedTerm){
return;
}
const {data} = yield cpAxios.get('https://en.wikipedia.org/w/api.php', {
params: {
action: 'query',
list: 'search',
origin: '*',
format: 'json',
srsearch: debouncedTerm,
}
});
setResults(data.query.search);
}, [debouncedTerm])
这可以简化为:
import { useAsyncEffect } from "use-async-effect2";
import cpAxios from "cp-axios";
// ...
const [cancel, done, results, err]= useAsyncEffect(function*(){
if(!debouncedTerm){
return;
}
const {data} = yield cpAxios.get('https://en.wikipedia.org/w/api.php', {
params: {
action: 'query',
list: 'search',
origin: '*',
format: 'json',
srsearch: debouncedTerm,
}
});
return data.query.search;
}, { states: true, deps: [debouncedTerm] });
console.log('results state:', results);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.