【问题标题】:Why React Component renders twice为什么 React Component 渲染两次
【发布时间】:2019-10-27 01:35:45
【问题描述】:

我有这个代码:

const fetchRequest = useCallback( () => {
        setIsLoading( true );
        axios( {
            method: "GET",
            url: "https://bouvet.guru/rekrytering_flera.php"
        } ).then( ( response ) => {
            if ( response.data.indexOf( "https://" ) !== -1 ) {
                let splittedArray = response.data.split( "Data:" );
                let dataString = splittedArray[1];

                if ( dataString.includes( "<URL kommentar>" ) ) {

                    dataString.substring( 16 );
                    let pairedData = dataString.split( "http" );
                    pairedData.splice( 0, 1 );

                    const finalArray = pairedData.map( ( group ) => {
                        const url = group.split( " " )[0];
                        const comment = group.replace( url, "" );

                        // Return an object with the paired properties. ID is not optimal to be Math.random(), this is for demonstration purpose.
                        return { url: "http" + url, comment, id: Math.random() };

                    } );

                    setData( [ ...data, ...finalArray ] );
                    setIsLoading( false );
                } else {
                    console.log( "NOPE" );
                }
            } else {
                console.log( "We could not find any data" );
                setIsLoading( false );
            }
        } );
    }, [] );

    useEffect( () => {
        fetchRequest();
        setInterval( () => {
            fetchRequest();
        }, 30000 );
    }, [] );


    console.log( data );

这只是一个简单的 useEffect axios 调用,我在其中收到一个字符串,然后将其设置为状态,然后将其记录到控制台。

我总是得到 2 个相同的数组。

(我现在知道它是一个useCallback,但是在整个代码中它只是一个useEffect时遇到了同样的问题。

这个组件是独立的。

【问题讨论】:

标签: reactjs


【解决方案1】:

你可以这样做:

const fetchRequest = () => {
        setIsLoading( true );
        axios( {
            method: "GET",
            url: "https://bouvet.guru/rekrytering_flera.php"
        } ).then( ( response ) => {
            if ( response.data.indexOf( "https://" ) !== -1 ) {
                let splittedArray = response.data.split( "Data:" );
                let dataString = splittedArray[1];

                if ( dataString.includes( "<URL kommentar>" ) ) {

                    dataString.substring( 16 );
                    let pairedData = dataString.split( "http" );
                    pairedData.splice( 0, 1 );

                    const finalArray = pairedData.map( ( group ) => {
                        const url = group.split( " " )[0];
                        const comment = group.replace( url, "" );

                        // Return an object with the paired properties. ID is not optimal to be Math.random(), this is for demonstration purpose.
                        return { url: "http" + url, comment, id: Math.random() };

                    } );

                    setData( [ ...data, ...finalArray ] );
                    setIsLoading( false );
                } else {
                    console.log( "NOPE" );
                }
            } else {
                console.log( "We could not find any data" );
                setIsLoading( false );
            }
        } );
    };

    useEffect( () => {
        fetchRequest();
        const interval = setInterval( () => {
            fetchRequest();
        }, 30000 );
        return ()=>{clearInterval(interval);}
    }, [] );


    console.log( data );

【讨论】:

    【解决方案2】:

    很可能第二次渲染是由setIsLoading( false )触发的

    【讨论】:

    • 我也是这么想的,但是当我删除了关于setIsLoading的所有内容时,它也做了同样的事情
    • 那么需要更多信息。通常触发重新渲染的两件事是状态和道具更改。临时删除 setInterval 调用也可能有助于进一步调查。
    • 另外我建议添加更多调试日志,例如在调用axios(...)之前添加日志
    猜你喜欢
    • 2023-01-24
    • 2020-08-10
    • 2020-09-07
    • 2021-07-27
    • 2021-05-17
    • 2017-11-22
    • 1970-01-01
    • 2020-03-17
    相关资源
    最近更新 更多