I wrote a code that receives the api through React Hook and calls the api again in the child component by passing the id when clicking. However, there seems to be a problem in settingState with arrow function in useEffect or onClick of child component.
I would appreciate it if you could give me an answer on how to fix it.
Users.js
import axios from 'axios';
import React, { useState, useEffect } from 'react';
import UserInfo from './UserInfo';
function Users() {
const [users, setUsers] = useState(null)
const [loding, setLoding] = useState(false)
const [error, setError] = useState(false)
const [userId, setUserId] = useState(null)
const fetchUsers = async () => {
try {
setUsers(null)
setError(null);
setLoding(true)
const respnse = await axios.get('https://jsonplaceholder.typicode.com/users')
setUsers(respnse)
} catch (e) {
setError(e)
}
setLoding(false)
};
useEffect(() => {
fetchUsers();
}, []);
if (loding) return <div>loading...</div>
if (error) return <div>error....</div>
if (!users) return null;
return (
<>
<ul>
{
users.data.map(user =>
<li key={user.id} onClick={() => setUserId(user.id)} >
{user.username} ({user.name})
</li>
)
}
</ul>
<button onClick={fetchUsers}>
reload
</button>
{userId && <UserInfo id={userId} />}
</>
);
}
export default Users;
UserInfo.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
function UserInfo({ id }) {
const [userInfo, setUserInfo] = useState(null)
async function getUsersAPI() {
try {
const response = await axios.get(`https://jsonplaceholder.typicode.com/users/${id}`)
setUserInfo(response)
} catch (e) {
}
}
useEffect(() => {
getUsersAPI()
}, [userInfo])
if (!userInfo) {
return null;
}
const { data } = userInfo
return (
<>
<h2>{data.username}</h2>
<p>
<b>email: </b>{data.email}
</p>
</>
);
}
export default UserInfo;
It seems like you want id
to be a useEffect
dependency instead of userInfo.
Otherwise every time userInfo
changes the effect will run, it will call getUsersAPI
which in turns sets the value of userInfo
when axios resolves (thus causing an infinite loop).
import React, { useEffect, useState } from 'react';
import axios from 'axios';
function UserInfo({ id }) {
const [userInfo, setUserInfo] = useState(null)
async function getUsersAPI() {
try {
const response = await axios.get(`https://jsonplaceholder.typicode.com/users/${id}`)
setUserInfo(response)
} catch (e) {}
}
useEffect(() => {
getUsersAPI()
}, [id])
if (!userInfo) {
return null;
}
const { data } = userInfo
return (
<>
<h2>{data.username}</h2>
<p>
<b>email: </b>{data.email}
</p>
</>
);
}
export default UserInfo;