Reputation: 45
I want to fetch a name and a photo from a rest API called "randomuserAPI", to add to some kind of card in my website, but it just keeps fetching again and again in a loop, and never stops at one (I just want one random number and photo but it just keeps updating those things all the time).
This is my Course element, in which the card is created with the fetched data, which is fetched inside a function somewhere else.
import React, { useState } from 'react';
import '../App.css';
import {getUser} from '../library/getUsers.js'
const Course = ({author}) => {
const [userInfo, changeUserInfo] = useState('User')
const [userPhoto, changeUserPhoto] = useState('https://i.sstatic.net/l60Hf.png')
getUser(changeUserInfo, changeUserPhoto)
return(
<div className="course">
<h4>{userInfo}</h4>
<p>{author}</p>
<img src={userPhoto} width="200px" height="200px" alt=""></img>
</div>
);
}
export default Course;
And this is the function which fetches the API:
export async function getUser(changeUserInfo, changeUserPhoto){
await fetch('https://randomuser.me/api?results=3')
.then(res => res.json())
.then((user) => {
changeUserInfo(`${user.results[0].name.first} ${user.results[0].name.first}`)
changeUserPhoto(user.results[0].picture.large)
})
}
I don´t know if anything can be wrong here, but here's the App element:
import React from 'react';
import Course from './elements/course';
import './App.css';
function App() {
return (
<div className="app">
<Course
author = 'Tato Gucci'
/>
</div>
);
}
export default App;
Upvotes: 1
Views: 5514
Reputation: 21
Your concerns as far as I understood are:
You want a single result from the API.
You need the result to be constant and must not change.
Instead of using https://randomuser.me/api?results=3
use https://randomuser.me/api?results=1
You were fetching 3 results and expecting a single result.
To make the result constant you need to store the fetched result in database and check the data exist or not before fetching. You only need to fetch data if its not exist in your database.
Upvotes: 0
Reputation: 518
getUser
without any restriction will cause an infinity loop (component Course
render > call getUser
> change userInfo
and userPhoto
> trigger render Course
> call getUser
again > ...)
You have to put your function that cause side effect (fetch API) into useEffect
hook, in this context is getUser(changeUserInfo, changeUserPhoto)
function.
useEffect = (() => {
getUser(changeUserInfo, changeUserPhoto)
}, [])
The empty array is make sure getUser
function just run only once time.
You should read more about useEffect
hook
Upvotes: 0
Reputation: 58533
Issue :
render -> getUser -> setting State -> re-render -> getUser .....
const Course = ({author}) => {
const [userInfo, changeUserInfo] = useState('User')
const [userPhoto, changeUserPhoto] = useState('https://i.sstatic.net/l60Hf.png')
//------------- ISSUE -------------
// `getUser` get called when ever component get rendered
// and it is setting up state , so it is causing re-rendering
// so it's kind of infinte loop
// render -> getUser -> setState -> re-render .....
getUser(changeUserInfo, changeUserPhoto)'
return(
<div className="course">
<h4>{userInfo}</h4>
<p>{author}</p>
<img src={userPhoto} width="200px" height="200px" alt=""></img>
</div>
);
}
Solution :
You can put getUser
inside useEffect
: so it will get called only when component get mounts
useEffect(() => {
getUser(changeUserInfo, changeUserPhoto)
},[]);
Upvotes: 3