简体   繁体   中英

How does react useEffect work with useState hook?

Can someone explain what am I'm doing wrong? I have a react functional component, where I use useEffect hook to fetch some data from server and put that data to state value. Right after fetching data, at the same useHook I need to use that state value, but the value is clear for some reason. Take a look at my example, console has an empty string, but on the browser I can see that value.

import "./styles.css";
import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  function fetchHello() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("Hello World");
      }, 1000);
    });
  }

  const handleSetValue = async () => {
    const hello = await fetchHello();
    setValue(hello);
  };

  useEffect(() => {
    const fetchData = async () => {
      await handleSetValue();
      console.log(value);
    };

    fetchData();
  }, [value]);

  return (
    <div className="App">
      <h1>{value}</h1>
    </div>
  );
};

export default App;

Link to codesandbox .

The useEffect hook will run after your component renders, and it will be re-run whenever one of the dependencies passed in the second argument's array changes.

In your effect, you are doing console.log(value) but in the dependency array you didn't pass value as a dependency. Thus, the effect only runs on mount (when value is still "" ) and never again.

By adding value to the dependency array, the effect will run on mount but also whenever value changes (which in a normal scenario you usually don't want to do, but that depends)

import "./styles.css";
import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  function fetchHello() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("Hello World");
      }, 1000);
    });
  }

  const handleSetValue = async () => {
    const hello = await fetchHello();
    setValue(hello);
  };

  useEffect(() => {
    const fetchData = async () => {
      await handleSetValue();
      console.log(value);
    };

    fetchData();
  }, [value]);

  return (
    <div className="App">
      <h1>{value}</h1>
    </div>
  );
};

export default App;

Not sure exactly what you need to do, but if you need to do something with the returned value from your endpoint you should either do it with the endpoint returned value (instead of the one in the state) or handle the state value outside the hook

import "./styles.css";
import React, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  function fetchHello() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve("Hello World");
      }, 1000);
    });
  }

  const handleSetValue = async () => {
    const hello = await fetchHello();

    // handle the returned value here 

    setValue(hello);
  };

  useEffect(() => {
    const fetchData = async () => {
      await handleSetValue();

    };

    fetchData();
  }, []);

  // Or handle the value stored in the state once is set
  if(value) {
    // do something
  }

  return (
    <div className="App">
      <h1>{value}</h1>
    </div>
  );
};

export default App;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM