Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using useDispatch() inside useEffect(), action doesn't appear to be called immediately

I want to dispatch an action when a page is first mounted. This action set loading to be true immediately, then set it to false after 2 seconds.

Noticing that it has different behaviours when I use hooks/react component. When I write it in a react component using componentDidMount, everything works fine. But with hooks useEffect, there's a 0.3 second time gap before the load action is called. What leads to this tiny time gap? Shouldn't useEffect be equivalent to componentDidMount?

Running Example

CodeSandbox

useEffect()

import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";

import { load } from "./actions/user";

const Router = () => {
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(load(true));
  }, [dispatch]);
  const loading = useSelector(state => state.user.loading);
  if (loading) {
    return <div>Loading...</div>;
  }
  return <div style={{ backgroundColor: "red" }}>Loaded</div>;
};

export default Router;

componentDidMount()

import React, { Component } from "react";
import { connect } from "react-redux";

import { load } from "./actions/user";

class Router extends Component {
  componentDidMount() {
    this.props.load(true);
  }

  render() {
    const { loading } = this.props;
    if (loading) {
      return <div>Loading...</div>;
    }
    return <div style={{ backgroundColor: "red" }}>Loaded</div>;
  }
}

export default connect(
  state => ({
    loading: state.user.loading
  }),
  { load }
)(Router);
like image 586
Aonan Li Avatar asked Jan 26 '23 10:01

Aonan Li


1 Answers

That's because useEffect and componentDidMount run in different portions of the React lifecycle.

componentDidMount and useLayoutEffect run synchronously, at the end of the "commit phase".

useEffect runs asynchronously with a brief delay, separate from the "commit phase".

So no, they are not exactly equivalent.

like image 155
markerikson Avatar answered Feb 02 '23 04:02

markerikson