Home > front end >  React useState does not set the value that receives from Axios
React useState does not set the value that receives from Axios

Time:12-21

I'm trying to send a GET request to http://localhost:8080/api/RE/template/${pageId} to display template items that belong to a specific id of the page. This is what displays on the console,

enter image description here

TemplateRealEstate.js

const TemplateRealEstate = () => {

  const [loadedTemplates, setLoadedTemplates] = useState([])

  const pageId = useParams().pageId;

  const getTemplates = async () => {
    await axios({
      method: "GET",
      url: `http://localhost:8080/api/RE/template/${pageId}`,
      headers: "Content-type: application/json"
    })
      .then((res) => {
        console.log("Respond from the request -->", res)
        setTimeout(() => setLoadedTemplates(res.data.templates), 0);
        console.log("Res.data.templates -->", res.data.templates)
      })
      .catch((err) => {
        console.log(err)
      })

    console.log("Loaded Templates --> ", loadedTemplates)

  }

  useEffect(() => {
    getTemplates();
  }, [pageId])
    
 }

So far I tried, using useCallback, setTimeout. I tried to add loadedTemplates as a dependency to useEffect to render the page but then it renders infinite. It displays literally infinite console.logs. If I leave the dependencies empty, it still continues the same.

Since I have files in the form, normally I make a POST request as 'Content-Type': 'multipart/form-data'. I've also tried to change the headers in the GET request but still the same. Why this is happening? I've other GET requests that didn't have this problem at all.

CodePudding user response:

The update will be reflected in the next render. That's how react works by design.

Take this example:

const getTemplates = () => {
    console.log(loadedTemplates) // Current state

    axios({
      method: "GET",
      url: `http://localhost:8080/api/RE/template/${pageId}`,
      headers: "Content-type: application/json"
    }).then((res) => {
      setLoadedTemplates(res.data.templates);
      console.log(loadedTemplates) // This won't print the recently updated state, but the same it printed at the beginning of the function
    })
}

Check this: https://stackoverflow.com/a/54069332/4898348

CodePudding user response:

Everything you did is correct, except for the line

console.log("Loaded Templates --> ", loadedTemplates)

Because useState is an async function, it will be add to system stack to be call later. Therefore, that console.log placed there will show old value.

To show loadedTemplates value properly: move it outside, so the next render will show. for example:

...
useEffect(() => {
  getTemplates();
}, [pageId])

console.log("Loaded Templates --> ", loadedTemplates)
...

CodePudding user response:

Try to change

useEffect(() => {
    getTemplates();
  }, [pageId]) 

to

const location = useLocation()
useEffect(() => {
    getTemplates();
  }, [location])

Also don't forget to add location dependency from react router dom.. if you still facing any issue just lemme know. Thanks

  • Related