簡體   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