axios ForEach在使用中不起作用使用React的效果

omhiaaxx  于 2023-03-02  发布在  iOS
关注(0)|答案(4)|浏览(162)
    • 背景**
  • 该项目的想法是有一个不同应用程序的下拉菜单(材料UI中的 accordion )。
  • 为每个应用程序提供与之相关的API调用。
  • 为每个API提供传入和传出参数。

我成功地拥有了我的应用程序列表,并在每一个API下面涉及他们,但我阻止恢复每个API的参数。
显示内容如下所示:
申请编号1
─ ─空气污染指数1

  • -参数
    由于我还在学习React的一般知识,我在"API"检索方面遇到了麻烦。
    • 以下是我的代码:**
export default function documentationv2() {

    // Getteur - Setteur
    const [applis, setApplis] = useState([]);
    const [APIs, setAPIs] = useState({});
    const [parametres, setParametres] = useState({});

    // Chargement
    const loadRessources = () => {
        axios.get('/api/documentation/application')
        .then((response) => {
            setApplis(response.data);
        })
        .catch((error) => console.log(error));
    }
    
    // Liste des APIs pour une application
    const ListeAPI = (AppliID) => {
        axios.get('/api/documentation/api?app_id=' + AppliID)
        .then((response) => {
            setAPIs(prev => {
                return {
                    ...prev,
                    [AppliID]: response.data
                }
            })
        })
    }

    // Liste des paramètres pour une API
    const ListeParametre = (IdAPI) => {
        console.log('ID : ' + IdAPI)
        axios.get('/api/documentation/parametre?api_id=' + IdAPI)
        .then((response) => {
            setParametres(prev => {
                return {
                    ...prev,
                    [IdAPI]: response.data
                }
            })
        })
    }

    useEffect(() => {
        if (applis == "" ) {
            loadRessources();
        }
        else{
            console.log('Length Appli : ' + applis.length)
            console.log('Appli : ' + applis.toString())
            applis.length && applis.forEach((application) => ListeAPI(application.IDAPPLI));
        }
    }, [applis])

    useEffect(() => {
        console.log('Length API : ' + APIs.length)
        console.log('API : ' + APIs)
        // APIs.length && 
        APIs.length && Object.values(APIs).forEach((api) => ListeParametre(api.api_id));
    }, [APIs])

    return (
        <Grid container className={classes.root}>
            {/* -- BODY -- */}
            <Grid item className={classes.Body}>
                <Grid container className={classes.GridContainerBody}>
                    {applis.map((application, index) => (
                        <div className={classes.DivContainerBody}>
                            <Grid item className={classes.GridItemLeftBody}>
                                <Accordion key={application.IDAPPLI} className={classes.AccordionBody}>
                                    <AccordionSummary expandIcon={<IconButton className={classes.ButtonBodyShow} disableRipple={true}><ExpandMoreIcon/></IconButton>}>
                                        <Typography>
                                            {application.NOMAPPLI} - ({application.NBAPI})
                                        </Typography>
                                    </AccordionSummary>
                                    <AccordionDetails className={classes.AccordionDetailsApplication}>
                                        {APIs[application.IDAPPLI] && APIs[application.IDAPPLI].map((api, index) => (
                                            <div className={classes.DivDetailsApplication}>
                                                <Accordion key={api.api_id} className={classes.AccordionBody}>
                                                    <AccordionSummary expandIcon={<IconButton className={classes.ButtonBodyShow} disableRipple={true}><ExpandMoreIcon/></IconButton>}>
                                                        <div className={classes.AccordionSumAPI}>
                                                            <Typography>
                                                                {api.api_uri}
                                                            </Typography>
                                                            <Typography>
                                                                {api.api_description}
                                                            </Typography>
                                                            <div className={classes.AccordionSumAPIDiv}>
                                                                <Chip
                                                                    style={{backgroundColor: "#06d6a0", width: "fit-content"}}
                                                                    label={api.api_version}
                                                                />
                                                                <Chip
                                                                    style={{backgroundColor: "#ffd166", width: "fit-content"}}
                                                                    label={api.api_response_type}
                                                                />
                                                            </div>
                                                            <div>
                                                                <Typography>
                                                                    Créé par {api.api_creation_user} le {api.api_date_creation}.
                                                                </Typography>
                                                                <Typography>
                                                                    Modifié par {api.api_maj_user} le {api.api_date_maj}.
                                                                </Typography>
                                                            </div>
                                                        </div>
                                                    </AccordionSummary>
                                                    <AccordionDetails className={classes.GridContainerBody}>
                                                    {parametres[api.api_id] && parametres[api.api_id].map((parametre, index) => (
                                                        <div key={index}>
                                                            <Typography>
                                                                Paramètre(s) d'entrée :
                                                            </Typography>
                                                            <Divider className={classes.ParamDivider}/>
                                                            <Chip
                                                                style={{backgroundColor: "#06d6a0", width: "fit-content"}}
                                                                label={parametre.INPUT}
                                                            />
                                                            <Typography style={{marginTop: "1%"}}>
                                                                Paramètre(s) de sortie :
                                                            </Typography>
                                                            <Divider className={classes.ParamDivider}/>
                                                            <Chip
                                                                style={{backgroundColor: "#ffd166", width: "fit-content"}}
                                                                label={parametre.OUTPUT}
                                                            />
                                                        </div>
                                                    ))}
                                                    </AccordionDetails>
                                                </Accordion>
                                            </div>
                                        ))}
                                    </AccordionDetails>
                                </Accordion>
                            </Grid>

                            <Grid item className={classes.GridItemRightbody}>
                                <div>
                                    <Tooltip title="Mot de passe" placement="top" arrow>
                                        <IconButton 
                                            className={classes.ButtonHeader}
                                            disableRipple={true}
                                        >
                                            <LockIcon/>
                                        </IconButton>
                                    </Tooltip>
                                </div>
                                <div>
                                    <Tooltip title="Télécharger doc
                                    " placement="top" arrow>
                                        <IconButton 
                                            className={classes.ButtonHeader}
                                            disableRipple={true}
                                        >
                                            <GetAppIcon/>
                                        </IconButton>
                                    </Tooltip>
                                </div>
                            </Grid>
                        </div>
                    ))}
                </Grid>
            </Grid>
            
        </Grid>
    )
}

您可以看到,我试图为参数重现与API相同的方法。
我可以看到我的常量"ListeParametre"没有被调用,而是被调用了Object.values(API)(我知道API是一个对象,必须将其转换为Array才能应用forEach

APIs.length && Object.values(APIs).forEach((api) => ListeParametre(api.api_id));

但是现在没有发送任何参数,Axios调用时会出现错误
(console.log('ID : ' + IdAPI)未定义)
注意:API.length似乎未定义

    • 编辑1:**通过console. log(对象条目(API))进入API内部
API : [["1", [{"api_id": IdValue, "api_uri": UriValue, "api_description": DescriptionValue, ...}, {...}]]]
    • EDIT 2:**在API上使用Object. entries时,它似乎会进入第一个应用程序的API的第一行。但随后会出现404错误,因为api_id未定义。
useEffect(() => {
    Object.entries(APIs).length && Object.entries(APIs).forEach((api) => ListeParametre(api.api_id))
}, [APIs])

有人能解释一下我的错误吗?谢谢你的帮助!如果我的问题/标题不清楚,请告诉我,我可以编辑它。

7fyelxc5

7fyelxc51#

为什么要在对象上调用.length
因为您已将Object设置为空状态
const [APIs, setAPIs] = useState({});
并且您正在对象上调用.length函数,因为它仅用于数组
我想这就是为什么它从来不为真它每次都返回未定义
你可以这样使用:
Object.entries(API).length && Object.values(APIs).forEach((api) => ListeParametre(api.api_id));

v6ylcynt

v6ylcynt2#

if (applis == "" ) {
    loadRessources();
}
else {
    console.log('Length Appli : ' + applis.length)
    console.log('Appli : ' + applis.toString())
    applis.length && applis.forEach(
        (application) => ListeAPI(application.IDAPPLI)
    );
}

对不起,这种代码的和平对我来说没有意义,也许你可以在API调用中提供带有存根的沙箱示例?
在这里,您检查applis是否为空字符串,但默认情况下将其设置为array,因此除非将applis设置为string,否则此语句将始终为false,并且您设置applic的唯一位置是loadRessources函数
然后在“else”语句中检查applis是否具有长度,但它将始终为空数组,因为在该if语句中调用了设置applis(loadRessources)的函数,而该函数永远不会执行

r9f1avp5

r9f1avp53#

我认为这里是错误的:

if (applis == "" ) {
    loadRessources();
}

loadRessources中,你调用setApplis,你想调用loadRessourcesif (applis == "" ),但是你设置状态的方式是这样的。

const [applis, setApplis] = useState([]);

所以if语句应该是

if (applis === []) {
    loadRessources();
}

您正在设置ListeAPI内部的API,该API在以下情况下调用:

applis.length && applis.forEach(
    (application) => ListeAPI(application.IDAPPLI)
);

由于您从未调用过loadRessources,因此不会设置applis,也不会调用ListeAPI。由于未调用setAPIs,因此不会设置setAPIs,因为您是在ListeAPI内部设置它。
由于未设置API,因此APIs.length是错误的。

fbcarpbf

fbcarpbf4#

在您的EDIT1:我看到对象是多个数组。

[
    [
        "1",
        [
            {
                "api_id": IdValue,
                "api_uri": UriValue,
                "api_description": DescriptionValue,
                ...
            },
            {...}
         ]
    ]
]

我觉得你可以试试这个

APIs.length > 0 &&
APIs[0].length > 1 &&
APIs[0][1].length > 0 &&
APIs[0][1].forEach((api) => ListeParametre(api.api_id))

相关问题