Issue
I have a React component that's main purpose is to display a list of profile names. The profile names are stored in a useState variable called profiles.
I have a useEffect in place on the component that effectively calls our API route to return the profile data we need on the frontend and place that data in the state variable for profiles.
If the profiles state variable has a length of zero, then we don't have the data and a logo will appear to load, otherwise the profiles should be mapped through and displayed as h1 tags.
While a console.log shows to me I am returning the data I need, I am getting the following error in my console "Uncaught TypeError: profiles.map is not a function".
Here is my code:
function ProfileListComponent() {
const fetchProfiles = async (payload) => {
const token = localStorage.getItem("token")
const response = await axios.get("http://127.0.0.1:5000/profiles", {headers:{
"Authorization": `Bearer ${token}`
}})
if (response.data) {
let profileData = []
for (let key in response.data) {
let profile = [
response.data[key].profile_id,
response.data[key].profile_name,
response.data[key].flow_rate,
response.data[key].hv,
response.data[key].lv,
response.data[key].duty_cycle,
response.data[key].frequency,
]
profileData.push(profile)
}
console.log(profileData)
return profileData
}
}
const [profiles, setProfiles] = useState([])
const compileProfileData = () => {
return ""
}
useEffect(() => {
try {
const profileData = fetchProfiles()
setProfiles(profileData)
} catch (error) {
console.log(error)
}
}, [])
return (
<div>
{profiles.length === 0 ?
<img src={logo} className="App-logo" alt="logo" />
: (
profiles.map(profile => <h1 className="profileBox" key={profile[0]} onClick={() => {compileProfileData(profile)}}>{profile[1]}</h1>
)
)}
</div>
)
}
I have tried different methods to conditionally render this data, though I always seem to error out with the same message indicating that the state variable isn't even an array (which is interesting considering its default value is an empty array).
Does anyone have some guidance to offer on how to correctly get this data rendered?
Solution
This happens because inside useEffect
hook try-catch
block executes both fetchProfiles
and setProfiles
synchronously. So setProfiles
sets a promise which has not resulted yet and below map function means "Give me array, not a promise"
.You should put your setState
inside fetchProfiles.
From this;
const fetchProfiles = async () => {
// const profileData = await axios ...
return profileData;
};
useEffect(() => {
try {
const data = fetchProfiles();
setProfiles(data); // SETS HERE
} catch (error) {
console.log(error);
}
}, []);
To this;
const fetchProfiles = async () => {
// const profileData = await axios ...
setProfiles(profileData); // SETS HERE
};
useEffect(() => {
try {
const data = fetchProfiles();
} catch (error) {
console.log(error);
}
}, []);
Imagine profileData
is constant mock data. And you can try this at
Stackblitz link
Answered By - configtheworld Answer Checked By - David Marino (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.