Im having problems with my effect hook. I only want it to render once. if I pass album.length or an empty array it returns an empty object. If the album is added as a dependency then the effect renders as an infinite loop. any help is appreciated.
const [album, setAlbum] = React.useState(initialState)
const {state} = React.useContext(AuthContext);
async function fetchData(){
try{
const res =await axios.get('http://localhost:5000/api/albums/all')
const {data}= await res;
setAlbum({...data,albums:res.data})
console.log(album)
}
catch(err){
console.log(err);
}
}
useEffect(() => {fetchData();}, []);
_______________________________________________________
componentDidMount(){
axios.get('http://localhost:5000/api/albums/all')
.then(res=>{
let albums=res.data.map((album)=>{
return(
<div key={album._id}>
//display the album
</div>
</div>
</div>
)
})
this.setState({albums:albums});
}) }
const res =await axios.get('http://localhost:5000/api/albums/all')
const {data}= await res;
setAlbum({...data,albums:res.data})
Can you please explain this? Why await res and why spread data and add it as albums as well?
You could write your own hook. You should also declare the function fetchApi
within the useEffect hook, that is why it re-renders the whole time.
Let's take your code and make a custom hook
import axios from 'axios';
import React, { useEffect, useState } from 'react';
function useAlbums() {
const [albums, setAlbums] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
const { data } = await axios.get(
'http://localhost:5000/api/albums/all',
);
setAlbums(data);
console.log(albums);
} catch (err) {
console.log(err);
}
};
fetchData();
}, [albums]);
return [albums, setAlbums];
}
const Component = () => {
// use it in component
const [albums] = useAlbums();
return (
<>
{albums.map(({ _id }) => (
<div key={_id}>{'add more content here'}</div>
))}
</>
);
};
Use with
const [albums, setAlbums] = useAlbums();
Hope this helps!
Effects always run after the browser finishes to paint (except useLayoutEffect
). Fetching data (which will be serialized into state
) inevitably will trigger an additional render
const [data, setData] = useState(null)
useEffect(() =>{
fetchAPI().then(res => setData(res))
},[])//Will run after the first render and trigger another one
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.