0
function MyFunction() {
    const [service, setService] = useState(); 

    useEffect(() => {
        const service = new ApiService();
        //service.getData().then((res) => console.log(res)); // works!
    
        setService(service);
        loadData();
    }, [])


    async function loadData() {
        const result = await service.getData(); // service is undefined!
        console.log(result);
    }
}

Why service is undefined? Can I use a Class Component instance inside a Functional Component?

Mikhail
  • 101
  • 2
  • 8
  • 1
    Please explain what are you trying to do, invoking Class Component constructor has no useful meaning, I guess you trying to call a static helper function? Please show how your API service defined, why its a Class Component and no a util class? – Dennis Vash Jul 26 '21 at 13:50
  • undefined means service hasn't been assigned a value. You can use instances of classes inside functional components – Mr. Robot Jul 26 '21 at 13:50
  • It's undefined because `setService` is async. – jmargolisvt Jul 26 '21 at 13:53
  • 1
    At the time you are calling `loadData`, the `service` state is still undefined because `setService` is async. You would need to use `useEffect` for instance, to detect a change in the state's value before calling loadData. See this https://stackoverflow.com/questions/54119678/is-usestate-synchronous – Micah Jul 26 '21 at 13:55

1 Answers1

0

Service is undefined when you call loadData() function, because React state is updated asynchronously. In order to achieve this you can call loadData() in the useEffect and passing service as a dependency there. Reference: React docs: State Updates May Be Asynchronous

The sample code will look like this now:

function MyFunction() {
  const [service, setService] = useState(); 

  useEffect(() => {
      const service = new ApiService();
      //service.getData().then((res) => console.log(res)); // works!

      setService(service);
  }, [])

  // implement to loadData() only when service state is updated
  useEffect(() => {
       // Additional check to verify service is defined properly
       if(service) loadData();
  }, [service])

  async function loadData() {
      const result = await service.getData(); // service is undefined!
      console.log(result);
  }
}