繁体   English   中英

React useEffect 警告警告:无法对未安装的组件执行 React 状态更新

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM