Shivam
Shivam

Reputation: 103

setInterval calls in functional components using hooks in ReactJS

In a ReactJs app, setInterval is being used in the demo below. Currently, it waits for 10 seconds even at inital load, instead, it should call immediately then after 10 second it should call again. How can i achieve this?

const callApiAfterOneSec = async () => {
    await axios.get(`https://jsonplaceholder.typicode.com/posts/${id}`)
          .then(res => {
              setLoading(false);
              setPost(res.data);
          })
          .catch(err => {
              setLoading(false);
              console.log(err);
          });
};

useEffect(() => {
    const interval = setInterval(callApiAfterOneSec, 10000);
    return () => {
        clearInterval(interval);
    };
}, [post]);

Upvotes: 0

Views: 143

Answers (3)

G2 Jakhmola
G2 Jakhmola

Reputation: 811

You could use this as class component

class App extends React.Component {

      interval;
      constructor() {
        super()
        this.state = {
          data: {}
        }
      }
      componentDidMount() {
        this.loadData();
        this.interval = setInterval(this.loadData, 5000);
      }

      componentWillUnmount() {
        clearTimeout(this.interval);
      }

      async loadData() {
        try {
          const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
          await res.json().then(res => {

            this.setState({
              data: res
            })
          })
        } catch (e) {
          console.log(e);
        }
      }

      render() {
        return (
          <div>
            <ul>
              <li>UserId : {this.state.data.userId}</li>
              <li>Title : {this.state.data.title}</li>
              <li>Body : {this.state.data.body}</li>
            </ul>
          </div>
        );
      }

    }
    render(<App />, document.getElementById('root'));

As @xadm mention you can useEffect two times as per requirement simple fix

useEffect(() => {
  callApiAfterOneSec();
}, []);

Upvotes: 1

xadm
xadm

Reputation: 8418

Try to add another useEffect(), fired only once:

useEffect(() => {
  callApiAfterOneSec();
}, []);

Upvotes: 1

Muhammad Zeeshan
Muhammad Zeeshan

Reputation: 4748

This is just a hack that might solve you problem.

const [rendered, setRendered] = useState(false);

useEffect(() => {
  let interval = null;
  if(rendered) interval =  setInterval(callApiAfterOneSec, 10000)
  setRendered(true);

  return () => {
    clearInterval(interval)
  }
}, [post, rendered])

Upvotes: 0

Related Questions