当我获取数据时,Sethooks的反应功能组件奇怪的行为

发布于 2025-01-31 15:58:44 字数 3585 浏览 6 评论 0原文

我有一个我需要工作的React类,必须将其更改为功能组件以使用USELocation()。

事实证明,通过切换到功能组件,我的状态的更新不再正常。

我的功能是在此

import * as React from "react";
import { useEffect, useState } from "react";
import Axios from "axios";
import { useLocation } from "react-router-dom";

const URL = `my-path`; 

const Sessions: React.FC<{ loadingParam?: boolean | undefined, someBooleanParam?: boolean | undefined, data?: AnyType[] | undefined }> = ({ loadingParam = true, someBooleanParam = undefined, data = undefined}) => {
                        
    const [loading, setLoading] = useState(loadingParam);
    const [someBoolean, setSomeBoolean] = useState(someBooleanParam);
    const [dataFetch, setDataFetch] = useState(data);

    const location:any = useLocation();

    useEffect(() => 
        {
            if(location.state == null){
                console.log("first implementation");
            } else {
                const dataToFill:AnyType[]|undefined = location.state.data;
                if( data ) {
                    setDataFetch(dataToFill);
                    setLoading(false);
                    setSomeBoolean(undefined);
                }
            }
        }
        ,
        [setDataFetch, setLoading, setSomeBoolean]
    );

    async function fetchData() {
        try {
            setLoading(true);
            await Axios.get<AnyType[]>(URL)
                .then(res => {
                    if (res.status === 200 && res != null) {
                        console.log("1 ", dataFetch); //undefined
                        console.log("1 bis ", res.data); //the data I want in the form I want
                        var copy:AnyType[] = [...res.data];

                        setDataFetch([...res.data]);

                        console.log("2 ", dataFetch); //undefined
                        console.log("2 ter ", copy);  //the data I want in the form I want

                        setDataFetch(copy);
                        console.log("2 ", dataFetch); //undefined

                        setLoading(false);

                        if (dataFetch?.length === parseInt(someValue)){
                            setSomeBoolean(true);
                        } else {
                            setSomeBoolean(false);
                        }
                    } else {
                        console.log('problem when fetching the data from backend');
                    }
                })
                .catch(error => {
                    console.log(error);
                });
        } 
        catch (exception) {
          console.log(exception);
        }
    }

    console.log("8 ", dataFetch); //Appears in the web console several times during the execution of the fetchData function with the data I want 

    return(
        <div className="container">
            <div>
                <button onClick={fetchData}> Click to get data </button>
            </div>
            {(someBoolean == true && loading == false) ? 
                Some Action
                : <></>
        </div>
    );
}

export default Sessions;

代码中,在fetchdata函数中,我需要知道datafetch数组的大小以设置某个boolean的值,但是在运行时,datafetch并未在try块中定义。但是,当我在同一功能中创建副本时,它的定义很好,我不明白。

我还试图通过将其置于异步函数中,从而回电了,但它给了我类似的结果,从而从我的fetchdata函数中拨打了呼叫。

我还尝试使FetchData函数无需尝试/捕获块,但结果仍然相同。

我需要的是,在fetchdata函数中,在。在。然后阻止流程停止以填充我的datafetch,然后检查数组的大小,然后渲染我的组件。但是我不想放置一个settimeout,因为我认为这是一种过于静态的行为。还有另一种方法吗?

有人看到我在这个可以解释这种行为的代码中做错了什么?

在此先感谢任何会花时间帮助我的人

I had a React class that did the job I needed and I had to change it to a functional component to use useLocation().

It turns out that by switching to a functional component the update of my states does not work normally anymore.

My function is in this form

import * as React from "react";
import { useEffect, useState } from "react";
import Axios from "axios";
import { useLocation } from "react-router-dom";

const URL = `my-path`; 

const Sessions: React.FC<{ loadingParam?: boolean | undefined, someBooleanParam?: boolean | undefined, data?: AnyType[] | undefined }> = ({ loadingParam = true, someBooleanParam = undefined, data = undefined}) => {
                        
    const [loading, setLoading] = useState(loadingParam);
    const [someBoolean, setSomeBoolean] = useState(someBooleanParam);
    const [dataFetch, setDataFetch] = useState(data);

    const location:any = useLocation();

    useEffect(() => 
        {
            if(location.state == null){
                console.log("first implementation");
            } else {
                const dataToFill:AnyType[]|undefined = location.state.data;
                if( data ) {
                    setDataFetch(dataToFill);
                    setLoading(false);
                    setSomeBoolean(undefined);
                }
            }
        }
        ,
        [setDataFetch, setLoading, setSomeBoolean]
    );

    async function fetchData() {
        try {
            setLoading(true);
            await Axios.get<AnyType[]>(URL)
                .then(res => {
                    if (res.status === 200 && res != null) {
                        console.log("1 ", dataFetch); //undefined
                        console.log("1 bis ", res.data); //the data I want in the form I want
                        var copy:AnyType[] = [...res.data];

                        setDataFetch([...res.data]);

                        console.log("2 ", dataFetch); //undefined
                        console.log("2 ter ", copy);  //the data I want in the form I want

                        setDataFetch(copy);
                        console.log("2 ", dataFetch); //undefined

                        setLoading(false);

                        if (dataFetch?.length === parseInt(someValue)){
                            setSomeBoolean(true);
                        } else {
                            setSomeBoolean(false);
                        }
                    } else {
                        console.log('problem when fetching the data from backend');
                    }
                })
                .catch(error => {
                    console.log(error);
                });
        } 
        catch (exception) {
          console.log(exception);
        }
    }

    console.log("8 ", dataFetch); //Appears in the web console several times during the execution of the fetchData function with the data I want 

    return(
        <div className="container">
            <div>
                <button onClick={fetchData}> Click to get data </button>
            </div>
            {(someBoolean == true && loading == false) ? 
                Some Action
                : <></>
        </div>
    );
}

export default Sessions;

In this code, in the fetchData function, I need to know the size of the dataFetch array to set the value of someBoolean, but at run time dataFetch is not defined in the try block. But when I create a copy in this same function it is well defined, I don't understand it.

I also tried to get the call to Axios out of my fetchData function by putting it in an asynchronous function that returned a promise but it gave me a similar result.

I also tried to make the fetchData function non-asynchronous without the try/catch block but still the same result.

What I will need is that in the fetchData function, in the .then block the flow stops to fill my dataFetch then check the size of the array and then render my component. But I don't want to put a setTimeout because it's a too static behavior I think. Is there another way to do it?

Does anyone see what I am doing wrong in this code that would explain this behavior?

Thanks in advance for anyone who would take the time to help me

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别把无礼当个性 2025-02-07 15:58:44

一种方法是将setsomeBoolean零件放入另一个使用时,该在datafetch更改时运行。类似的事情:

import * as React from "react";
import { useEffect, useState } from "react";
import Axios from "axios";
import { useLocation } from "react-router-dom";

const URL = `my-path`; 

const Sessions: React.FC<{ loadingParam?: boolean | undefined, someBooleanParam?: boolean | undefined, data?: AnyType[] | undefined }> = ({ loadingParam = true, someBooleanParam = undefined, data = undefined}) => {
                        
    const [loading, setLoading] = useState(loadingParam);
    const [someBoolean, setSomeBoolean] = useState(someBooleanParam);
    const [dataFetch, setDataFetch] = useState(data);

    const location:any = useLocation();

    useEffect(() => 
        {
            if(location.state == null){
                console.log("first implementation");
            } else {
                const dataToFill:AnyType[]|undefined = location.state.data;
                if( data ) {
                    setDataFetch(dataToFill);
                    setLoading(false);
                    setSomeBoolean(undefined);
                }
            }
        }
        ,
        [setDataFetch, setLoading, setSomeBoolean]
    );

    useEffect(()=>{
        if (dataFetch?.length === parseInt(someValue)){
            setSomeBoolean(true);
        } else {
            setSomeBoolean(false);
        }
        setLoading(false);
    },[dataFetch])


    async function fetchData() {
        try {
            setLoading(true);
            await Axios.get<AnyType[]>(URL)
                .then(res => {
                    if (res.status === 200 && res != null) {
                        console.log("1 ", dataFetch); //undefined
                        console.log("1 bis ", res.data); //the data I want in the form I want
                        var copy:AnyType[] = [...res.data];

                        setDataFetch([...res.data]);

                        console.log("2 ", dataFetch); //undefined
                        console.log("2 ter ", copy);  //the data I want in the form I want

                        setDataFetch(copy);
                        console.log("2 ", dataFetch); //undefined


                    } else {
                        console.log('problem when fetching the data from backend');
                    }
                })
                .catch(error => {
                    console.log(error);
                });
        } 
        catch (exception) {
          console.log(exception);
        }
    }

    console.log("8 ", dataFetch); //Appears in the web console several times during the execution of the fetchData function with the data I want 

    return(
        <div className="container">
            <div>
                <button onClick={fetchData}> Click to get data </button>
            </div>
            {(someBoolean == true && loading == false) ? 
                Some Action
                : <></>
        </div>
    );
}

export default Sessions;

我也不知道为什么您想要[setDatafetch,setloading,setSomeBoolean]作为第一个useffect的依赖项数组?

One way would be to put the setSomeBoolean part into another useEffect which runs when the dataFetch changes. Something like that:

import * as React from "react";
import { useEffect, useState } from "react";
import Axios from "axios";
import { useLocation } from "react-router-dom";

const URL = `my-path`; 

const Sessions: React.FC<{ loadingParam?: boolean | undefined, someBooleanParam?: boolean | undefined, data?: AnyType[] | undefined }> = ({ loadingParam = true, someBooleanParam = undefined, data = undefined}) => {
                        
    const [loading, setLoading] = useState(loadingParam);
    const [someBoolean, setSomeBoolean] = useState(someBooleanParam);
    const [dataFetch, setDataFetch] = useState(data);

    const location:any = useLocation();

    useEffect(() => 
        {
            if(location.state == null){
                console.log("first implementation");
            } else {
                const dataToFill:AnyType[]|undefined = location.state.data;
                if( data ) {
                    setDataFetch(dataToFill);
                    setLoading(false);
                    setSomeBoolean(undefined);
                }
            }
        }
        ,
        [setDataFetch, setLoading, setSomeBoolean]
    );

    useEffect(()=>{
        if (dataFetch?.length === parseInt(someValue)){
            setSomeBoolean(true);
        } else {
            setSomeBoolean(false);
        }
        setLoading(false);
    },[dataFetch])


    async function fetchData() {
        try {
            setLoading(true);
            await Axios.get<AnyType[]>(URL)
                .then(res => {
                    if (res.status === 200 && res != null) {
                        console.log("1 ", dataFetch); //undefined
                        console.log("1 bis ", res.data); //the data I want in the form I want
                        var copy:AnyType[] = [...res.data];

                        setDataFetch([...res.data]);

                        console.log("2 ", dataFetch); //undefined
                        console.log("2 ter ", copy);  //the data I want in the form I want

                        setDataFetch(copy);
                        console.log("2 ", dataFetch); //undefined


                    } else {
                        console.log('problem when fetching the data from backend');
                    }
                })
                .catch(error => {
                    console.log(error);
                });
        } 
        catch (exception) {
          console.log(exception);
        }
    }

    console.log("8 ", dataFetch); //Appears in the web console several times during the execution of the fetchData function with the data I want 

    return(
        <div className="container">
            <div>
                <button onClick={fetchData}> Click to get data </button>
            </div>
            {(someBoolean == true && loading == false) ? 
                Some Action
                : <></>
        </div>
    );
}

export default Sessions;

Also im not sure why you want [setDataFetch, setLoading, setSomeBoolean] as a dependency array of the first useEffect?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文