8

I recently used hooks with React to fetch data from server but i'm facing a problem with hooks. The code seems correct but it look like the useEffect isn't called at first time but 3 seconds after with the setInterval. I have blank table for 3 seconds before it appear. I want to directly show the data and call it 3 seconds later.

What is the correct way to use it?

const [datas, setDatas] = useState([] as any);

useEffect(() => {
  const id = setInterval(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(URL);
        const json = await res.json();
        setDatas(jsonData(json));
      } catch (error) {
        console.log(error);
      }
    };
    fetchData();
  }, TIME)

  return () => clearInterval(id);
}, [])

2 Answers 2

8

You need to invoke fetchData once initially outside the interval. Define fetchData outside the interval.

useEffect(() => {
  // (1) define within effect callback scope
  const fetchData = async () => {
    try {
      const res = await fetch(URL);
      const json = await res.json();
      setDatas(jsonData(json));
    } catch (error) {
      console.log(error);
    }
  };
    
  const id = setInterval(() => {
    fetchData(); // <-- (3) invoke in interval callback
  }, TIME);

  fetchData(); // <-- (2) invoke on mount

  return () => clearInterval(id);
}, [])
Sign up to request clarification or add additional context in comments.

2 Comments

You have a dangling promise here. If fetchData() take a while, they will start to pile up and call multiple fetchData() in parallel.
@MikaelLirbank Yes, I suppose long-running fetchData calls can pile up in this basic example. If concurrent fetches are a problem it's trivial to handle, e.g. cancel preceding in-flight requests, block new requests, etc.
-1

With React Hooks:

  const [seconds, setSeconds] = useState(0)

  const interval = useRef(null)

  useEffect(() => { if (seconds === 60) stopCounter() }, [seconds])

  const startCounter = () => interval.current = setInterval(() => {
    setSeconds(prevState => prevState + 1)
  }, 1000)

  const stopCounter = () => clearInterval(interval.current)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.