繁体   English   中英

React UseState 未更新

[英]React UseState not being updated

我无法正确理解如何更新我的 useState。 我正在通过我的 Axios 电话接收数据,所以“applis”不是空的,但下面的内容似乎卡住了。

我想做什么:

  • 从包含应用程序列表的第一次调用中接收数据(名称、ID 和此应用程序具有的 API 数量)
  • 获取应用程序的 ID 进行第二次调用,这将为我带来该应用程序的 API(感谢 ID)
  • 加载应用程序时的所有这些(我有 19 个应用程序和一百多个 API)

我可以在 Accordion 中显示我的不同应用程序,但在 AccordionSummary 中,您可以看到我无法获取应用程序的 API 列表。

要么我什么都没有(就像在这篇文章中那样),要么所有的 API 都在一个应用程序下一遍又一遍地循环......

这是我的代码:

 export default function documentationv2() { // Getteur - Setteur const [applis, setApplis] = useState([]); const [applicationSelect, setApplicationSelect] = useState([]); const [APIs, setAPIs] = useState([]); // Chargement const loadRessources = () => { axios.get('/api/documentation/application').then((response) => { setApplis(response.data); console.log('LesApplications: ' + JSON.stringify(response.data)) {applis.map((application) => ( setApplicationSelect(application.IDAPPLI) ))} ListeAPI(applicationSelect); }).catch((error) => console.log(error)); } const ListeAPI = (AppliID) => { console.log('SELECT: ' + AppliID) // console.log('ID: ' + AppliID) axios.get('/api/documentation/api?app_id=' + AppliID).then((response) => { setAPIs(response.data) console.log('LesAPIS: ' + response.data) }) {APIs.map((api, index) => ( console.log('API: ' + api.api_uri) ))} } useEffect(() => { console.log('Chargement....') loadRessources(); }, []) // useEffect(() => { // console.log('-> Application SELECT: ' + applicationSelect) // axios.get('/api/documentation/api?app_id=' + 1) //.then((response) => { // setAPIs(response.data) // console.log('-> APIs: ' + response.data) // }) // }, [applicationSelect]) return ( {/* -- 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} onChange={(event) => setApplicationSelect(application.NOMAPPLI)} className={classes.AccordionBody}> <AccordionSummary expandIcon={<IconButton className={classes.ButtonBodyShow} disableRipple={true}><ExpandMoreIcon/></IconButton>}> <Typography> {application.NOMAPPLI} - ({application.NBAPI}) </Typography> </AccordionSummary> <AccordionDetails className={classes.AccordionDetailsApplication}> {/* {ListeAPI(application.IDAPPLI)} */} {/* {APIs.map((api, index) => ( <div className={classes.DivDetailsApplication}> <Accordion key={index} 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"}} label={api.api_version} /> <Chip style={{backgroundColor: "#ffd166"}} 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> <Typography> Information </Typography> </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> ) }

不同的 console.log 告诉我什么:

LesApplications : [{"NOMAPPLI" : "NameValue", "IDAPPLI" : "IdValue", "NBAPI" : "ValueCount"}, ...]

SELECT : 

LesAPIS : 

有人可以解释我的错误吗? 一定是 useEffect 没有重新渲染的东西? 我真的不明白这里的一切。

如果我的问题标题不清楚,请提前致歉

setApplis是异步的,你不能在applis.map之后调用setApplis因为你的applis还没有更新。 您必须在useEffect中调用applis.map并依赖它。 然后在第二个useEffect中,您使用实际的applicationSelect数组调用ListeAPI(applicationSelect)

例子:

 const loadRessources = () => {
        axios.get('/api/documentation/application')
        .then((response) => {
            setApplis(response.data);
            console.log('LesApplications : ' + JSON.stringify(response.data))
        })
        .catch((error) => console.log(error));
 }

  useEffect(() => {
    const arr = applis.map((application) => application.IDAPPLI);
    setApplicationSelect(arr);
  }, [applis]);

  useEffect(() => {
   applicationSelect.length && ListeAPI(applicationSelect);
  }, [applicationSelect]);

  useEffect(() => {
    loadRessources();
  }, [])

另一个例子:

 const ListeAPI = (AppliID) => {
    axios.get('/api/documentation/api?app_id=' + AppliID)
    .then((response) => {
        setAPIs(prev => [...prev, ...response.data])
        console.log('LesAPIS : ' + response.data)
    })
}

 const loadRessources = () => {
        axios.get('/api/documentation/application')
        .then((response) => {
            setApplis(response.data);
            console.log('LesApplications : ' + JSON.stringify(response.data))
        })
        .catch((error) => console.log(error));
 }


 useEffect(() => {
     applis.length && applis.forEach((application) => ListeAPI(application.IDAPPLI));
  }, [applis]);

  useEffect(() => {
    loadRessources();
  }, [])

示例如何执行正确的APIs object 结构:

const [APIs, setAPIs] = useState({});
const ListeAPI = (AppliID) => {
    axios.get('/api/documentation/api?app_id=' + AppliID)
    .then((response) => {
        setAPIs(prev => {
            return {
                ...prev,
                [AppliID]: response.data
            }
        })
    })
}

JSX,然后你可以通过applis id找到需要的api:

{applis.map((application, index) => (
    ...

    {APIs[application.IDAPPLI] && APIs[application.IDAPPLI].map((api, index) => (
        ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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