Home > database >  useState inside of useEffect not reflecting a change immediately
useState inside of useEffect not reflecting a change immediately

Time:07-03

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() or res.text() on the axios 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 call JSON.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 with file.data.comments
  • Related