最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React hooks - wait until the state has been updated - Stack Overflow

programmeradmin1浏览0评论

I'm using the useState() hook, and I've found that my app has a bug, because setting the value is asynchronous. So if I have code like this:

 const [data, setData] = useState([])
  useEffect(() => {
    const getData = async () => {
      const res = await fetchData()
      console.log(data); // []
      setData(res.data.hits);
      console.log(res.data.hits); // Array full of objects
      console.log(data); // Still []
    }
    getData()
  }, [fetchData]);

How can I execute some specific logic only when the new state has actually been set?

I'm using the useState() hook, and I've found that my app has a bug, because setting the value is asynchronous. So if I have code like this:

 const [data, setData] = useState([])
  useEffect(() => {
    const getData = async () => {
      const res = await fetchData()
      console.log(data); // []
      setData(res.data.hits);
      console.log(res.data.hits); // Array full of objects
      console.log(data); // Still []
    }
    getData()
  }, [fetchData]);

How can I execute some specific logic only when the new state has actually been set?

Share Improve this question edited Sep 9, 2020 at 15:47 GeForce RTX 4090 asked Sep 9, 2020 at 15:23 GeForce RTX 4090GeForce RTX 4090 3,49812 gold badges35 silver badges65 bronze badges 6
  • Even if it weren't asynchronous, data is still declared with const - it won't change – CertainPerformance Commented Sep 9, 2020 at 15:24
  • 1 What sort of "execute something" do you want? A side-effect, like an API call? Or do you want to change what's rendered, or something else? – CertainPerformance Commented Sep 9, 2020 at 15:25
  • Add a new effect that watches data – F.P Commented Sep 9, 2020 at 15:25
  • why don't you use conditional rendering? once the data are available then it will execute. – Siful I Commented Sep 9, 2020 at 15:32
  • @CertainPerformance The setState method has a callback when the state is updated. I'm looking for something similar to that. – GeForce RTX 4090 Commented Sep 9, 2020 at 15:37
 |  Show 1 more comment

3 Answers 3

Reset to default 11

You can use the useEffect hook:

useEffect(() => {
   //your code
}, [data]);

That will trigger what is inside every time data changes.

You can perform some logic to ensure the "specific logic" you want is executed after your setData is done from that specific call and not from other setData calls,

For example,

 const [data, setData] = useState([])
 const [runSpecific, setRunSpecific] = useState(false)
  useEffect(() => {
    const getData = async () => {
      const res = await fetchData()
      console.log(data); // []
      setData(res.data.hits);
      setRunSpecific(true);
      console.log(res.data.hits); // Array full of objects
      console.log(data); // Still []
    }
    getData()
  }, [fetchData]);

  useEffect(() => {
    if(runSpecific){
       "specific Logic" you want to run
    }
    setRunSpecific(false)
  }, [data]);

In essence, every time the data changes, it executes your "specific logic" only when runSpecific is true, which can only be true from that initial call.

So you need not worry when about other SetData calls.

With react 18, useEffect runs twice, but even with that, your logic will work here!

 const [data, setData] = useState([])
  useEffect(() => {
    const getData = async () => {
      const res = await fetchData()
      setData(res.data.hits);
    }
    if(!data.length){
      // logic for the time, when the state has not been updated yet
      getData()
    }else if(data.length){
      // logic for the time, when the state has been updated
      console.log("state is", state)
    }
  }, [data]); // only use [data], no need to put fetchData in the array

发布评论

评论列表(0)

  1. 暂无评论