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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With