'React Typescript project .map function working only one time after compilation

I want to create a frontend for my app using React and TypeScript. I am gathering data from my backend (simple DRF app) and fetching it using Axios and pushing it into separate arrays.

const myApi = axios.create({
    baseURL: 'http://127.0.0.1:8000/app/',
    headers: {
        "Content-type": "application/json"
    }
})

let idArr:number [] = new Array()
let titleArr:string [] = new Array()
let contentArr:string [] = new Array()


myApi.get('/getallarticles').then( res => {
    for(let elem in res.data)
    {
        idArr.push(res.data[elem].id)
        titleArr.push(res.data[elem].title)
        contentArr.push(res.data[elem].content)
    }
})

The app contains a page named feed into which I parse the id Array.

function App() {
    console.log(idArr)
    return (
      <Box>
        <Navbar/>
          <Grid alignItems={"center"} justifyContent={"center"} marginLeft={'15%'} marginRight={'15%'}>
              <Stack  spacing={2} margin={2}>
                  <Box id='res_viewer'>
                      <Feed content={"CONTENT FROM MAIN"} id={10} title={"Sherlock Holmes"} total={5} idArr={idArr}/>
                  </Box>
              </Stack>
          </Grid>
      </Box>
  );
}

Then in my page Feed I copy the ActionCard (from Mui5) and the problem is that all the Cards show only if I recompile the project. It only works one time, and I have no idea why. Moreover if I put the console.log and alert into the Feed the console.log would show an array every time, while Alert only the first time. Anyone have any idea what the issue might be?

const Feed = ({ id, title, content, total, idArr }: { id: number; title: string; content: string; total: number; idArr:Array<number>}) => {
    console.log(idArr)
    alert(idArr)
    return(
        <div>
            {idArr.map(customId =>
                <Card key={customId} variant="outlined" sx={{ margin: 0 }}>
                    <CardActionArea>
                        <CardContent>
                            <Typography gutterBottom variant="h5" component="div">
                                {customId}
                            </Typography>
                            <Typography variant="body2" color="text.secondary">
                                {content}
                            </Typography>
                        </CardContent>
                    </CardActionArea>
                    <CardActions>
                        <Button style={{
                            color: "#ff0000",
                        }} size="large" startIcon={<DeleteForever />}>
                            DELETE
                        </Button>
                        <Button style={{
                            color: "#68ee06",
                        }} size="large" startIcon={<Edit />}>
                            EDIT
                        </Button>
                    </CardActions>
                </Card>
            )}
        </div>
    )
}

export default Feed

enter image description here



Solution 1:[1]

I suspect the asynchronous nature of the call to your API is what's giving this behavior. When making calls to an API for data, it's common to use a useEffect hook that updates a state. This ensures that the UI is in sync with the data. Try rewriting as follows:

const myApi = axios.create({
    baseURL: 'http://127.0.0.1:8000/app/',
    headers: {
        "Content-type": "application/json"
    }
})

const [idArr, setIdArr] = useState([] as number[]);
const [titleArr, setTitleArr] = useState([] as string[]);
const [contentArr, setContentArr] = useState([] as string[]);

useEffect(() => {
  myApi.get('/getallarticles').then(res => {
    const newIds: number[] = [];
    const newTitles: string[] = [];
    const newContents: string[] = [];

    for (let elem in res.data) {
      newIds.push(res.data[elem].id);
      newTitles.push(res.data[elem].title);
      newContents.push(res.data[elem].content);
    }

    setIdArr(newIds);
    setTitleArr(newTitles);
    setContentArr(newContents);
  });
}, []);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ace