Combine class component and functional component React
Tags: react, javascript, hooks
Published: 2021-10-28 00:10:44

Using Functional Components in react become the most popular way to create react Components, sometimes I feel like I want to use a 
class component lifecycle functions but still want to get benefits from react hooks

it is simple tutorial about how to use useEffect hook as lifecycle functions in react.

lets start with the most simple one `componentDidMount()`
> will not write too much to describe the code I will try to name functions to describe it.

you can create it easily 

```js
    useEffect(function componentDidMount(){
        console.log("%c componetDidMount","color:green;")
    }, [])

```

to add `componentWillMount()` just add it as returned function for `componentDidMount()` Like

```js
    useEffect(function componentDidMount(){
        console.log("%c componetDidMount","color:green;")
        return function componentWillUnmount(){
            console.log("%c componetWillUnmount", "color:red")
        }
    }, [])

```

the next one will be a compine between `componentDidMount()` and `componentWillMount()`
it will be `componentDidMountAndCompontDidUpdate()` yeah it is not from react lifecycle component but will help to understand `useEffect`

```js
    useEffect(function componentDidMountAndCompontDidUpdate(){
        console.log("%c componentDidMountAndCompontDidUpdate","color:teal;")
    })

```

this function with no deps array will run twice in the rendering of the component. it will run at mount and after this it will run at update, This component will run every time after any state change.


The remaining Function is `componetDidUpdate()` to build a componentDidUpdate you need to create mounted flag.
run function only in componet update and ignore run in componet mount

```js
    const mounted = useRef()
    useEffect(function runComponentDidUpdate(){
        if(!isComponetMounted()) return;
        (function componentDidUpdate(){
            console.log("%c CompontDidUpdateForAnyVariable", "color:orange;")
        })()
    });
 
    useEffect(function lastUseEffect(){ // must be the last useEffect to check the component as mounted 
        signComponetAsMounted()
    }, [])

    function signComponetAsMounted(){
        mounted.current = true
    }

    function isComponetMounted(){
        if (!mounted.current) {
            return false
        }
        return true
    }
```

The whole code.
```js

import React, { useEffect, useRef, useState } from "react";

function FuctionComponentLifeCycle(){
    const mounted = useRef()
    const [count, setCount] = useState(0)

    useEffect(function componentDidMount(){
        console.log("%c componetDidMount","color:green;")
        return function componentWillUnmount(){
            console.log("%c componetWillUnmount", "color:red")
        }
    }, [])

    useEffect(function componentDidMountAndCompontDidUpdate(){
        console.log("%c componentDidMountAndCompontDidUpdate","color:teal;")
    })

   
    useEffect(function ComponentDidUpdateForCount(){
        console.log("%c CompontDidUpdateForCount", "color:blue;")
    }, [count])

    

    useEffect(function runComponentDidUpdate(){
        if(!isComponetMounted()){
            return 
        }
        (function componentDidUpdate(){
            console.log("%c CompontDidUpdateForAnyVariable", "color:orange;")
        })()
    });
 
    useEffect(function lastUseEffect(){
        signComponetAsMounted()
    }, [])

    function signComponetAsMounted(){
        mounted.current = true
    }

    function isComponetMounted(){
        if (!mounted.current) return false;
        return true;
    }

    return (
    <div>
        Component Rendered
        <div className="">
            {count}
        </div>
        <button onClick={()=>setCount(count=> count + 1 )}> Add 1</button>
    </div>
    )
}

export default FuctionComponentLifeCycle;

```

> NOTE Don't forget useState run async

Thanks for reading.