0

Please note the question is NOT about Asynchronous Nature of useState. It is Asynchronous and it's well answered here: useState set method not reflecting change immediately Please donot confuse this with that! I have used useEffect to get the button working, as shared in codepen

My question is can i add / include any asynchronous function within main component? Main Component: HelloWorld Sub function: interestShown => Can this be asynchronous? in the example i have simplified it as much as possible with console.log output.

Is this an advisable route or am i attempting something bizarre?

I have tried looking for solution to this problem, but I think all answers were directing me to classes, I am looking to get this going in React Functional Component if possible.

I have defined state like so: const [interested, setInterested] = React.useState(false)

when I call this function:

function interestShown() {
      console.log("Before Set State fired", interested)
      setInterested(!interested)
      console.log("After Set State Fired", interested)
    }

The after state change console log needs to show the changed state, I couldn't get this going, I tried many options

My problem is here in this code pen: https://codepen.io/deepeshkr/pen/PowQWwv

The console log output:

pen.js:6 Before Set State fired false

pen.js:8 After Set State Fired false => this should be true, but i am guessing this is asynchronous change, this is my question how to fire this After State Change?

pen.js:14 Fire only it's true true

There are similar sounding questions, but i am not sure they are asking the same thing as i am asking or question is well explained to demonstrate the problem.

indavinci
  • 155
  • 2
  • 3
  • 11
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – Emile Bergeron Jan 07 '20 at 19:58
  • @EmileBergeron yes it does, I was aware of asynchronous nature, but i was hoping for certain extreme cases, perhaps bad coding practises i was hoping to add a function to run asynchronously within the main component, looks like i cant! – indavinci Jan 07 '20 at 20:03
  • The value of the state variable is immutable for the scope of the function, so its value is never going to change. But since you're setting it yourself just before, use that value instead. `const newValue = !interested;` – Emile Bergeron Jan 07 '20 at 20:04
  • My solution is extend this to another component, do the work there can come back here, wrap this component around it.. hopefully that should work – indavinci Jan 07 '20 at 20:06

2 Answers2

1

Yes, it is asynchronous. So you won't see the changes immediately.

From the setState() documentation:

The setState() function is used to update the state. It accepts a new state value and enqueues a re-render of the component.

You can use useEffect() hook to capture state changes, from the documentation:

Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase). Doing so will lead to confusing bugs and inconsistencies in the UI.

You can import it like:

import React, { useState, useEffect } from 'react';

The following code snippet will help you to log interested state changes:

useEffect(() => {
   console.log(interested);
}, ['state has changed', interested]);

I hope that clarifies.

norbitrial
  • 14,716
  • 7
  • 32
  • 59
  • I have used useEffect to fire the function, but is there a way to use asynchronous code within function interestShown() ? my code pen: https://codepen.io/deepeshkr/pen/PowQWwv – indavinci Jan 07 '20 at 19:31
  • I think for this use-case `useEffect` is the proper way to check state changes. – norbitrial Jan 07 '20 at 19:35
  • My main function is HelloWorld the function i am talking about making these changes in function interestShown(), does that mean i cant make any changes in that one too? – indavinci Jan 07 '20 at 19:37
  • Try to add the if statement within your function and then call the function in useEffect – Logesh P Jan 07 '20 at 19:38
  • It's a toggle button which means if statements are not the best solution, i have tried to explain the problem in codepen. – indavinci Jan 07 '20 at 19:48
  • 1
    You're linking to the wrong `setState` documentation. OP is using hooks. The right documentation page is [`useState`](https://reactjs.org/docs/hooks-reference.html#usestate). – Emile Bergeron Jan 07 '20 at 20:00
0

I got the way i could do an asynhronous requests with react functional component using effect, posting here so it could help others,

  React.useEffect(() => {
    if (showReport) {
      fetch("https://website.com/json")           // Get the data external or internal
        .then(res => res.json())
        .then(ip => Promise.all([ip, getSomethingElse()]))    // Get something else, again external or internal function call
        .then(([ip, gp]) => {
          setData(gp);                               // Update the state
          setIp(ip);
          setShowReport(false);
        });
    }
  }, [showReport]);

Hope this helps others

indavinci
  • 155
  • 2
  • 3
  • 11