I did some research and I've learned that useState is asynchronous, although, I'm still not sure how to fix my particular issue. I need to fetch the data from an api, and the state only updates the second render, plus I need to get only 1 file, so just adding current new state to the previous one is probably not an option.
(the result is that it now says .map is not a function since useState is empty)
useEffect(() => {
axios.get(`http://localhost:8080/files/public/${id}`)
.then(res => {
console.log(res.data);
setFile(res.data);
})
}, []);
{
file.map((row, index) => {
return <li>{index}</li>
})
}
Edit: useState is actually initialized const [file, setFile] = useState([]);
CodePudding user response:
One reason you could get this error is if you have initialised the file
state without providing a value, meaning it has the value of undefined
(but we would need to see how you're declaring the state to confirm that). As undefined
is not a Prototype that has a native map
property (or any properties), you cannot call the map
property on the initial render.
You should be able to get rid of the error by initialising the state to an empty Array like this:
const [file, setFile] = useState([]);
Setting the initial state means that the first render will treat file
as an empty Array, so you can call map
on it and it will simply render nothing (as the Array is empty).
Sample Final Code:
const MyComponent = () => {
const [file, setFile] = useState([]);
useEffect(() => {
axios.get(`http://localhost:8080/files/public/${id}`).then((res) => {
console.log(res.data);
setFile(res.data);
});
}, []);
return (
<div>
{file.map((row, index) => {
return <li>{index}</li>;
})}
</div>
);
}
Update:
Another reason could be that the response you are getting from axios
isn't an Array. In this case, it could be a solution to:
- ensure you've called
res.json()
orres.text()
on theaxios
response (so you aren't handling a response Object, but are in fact handling the data); - If the data returned is a stringified Array (such as
'["comment 1","comment 2","etc..."]'
, you need to callJSON.parse
on it first; - If the response is an Object, make sure you're pointing to the correct path for the Array, for instance
{ data: { comments: [...] } }
should be accessed withfile.data.comments