Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Info

...

I was putting together some code to demonstrate how modifying a state variable causes a component to rerender.  All was going will until I put a timer on the component, that got the current and displayed it in the page.  That worked fine example 1, but it all changed when I wanted to keep a list of all the times and print them all out each time a new time was added, things a got a little weird, example 2. 

Example 1.

Get the time and continually display it

Code Block
languagejs
import React, { useState } from 'react'
import { useEffect } from 'react';

function getTheTime()
{
    let currentDate = new Date();
    let currentTime = currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds();
    return currentTime;
}

export default function FCDisplayTimeInSameSpot(){
    console.log("Executing FCDisplayTimeInSameSpot()");
    
    const [containerState, setContainerState] = useState([getTheTime()]);
  
    const getDisplayData = () => {
        const cdata = containerState
        return cdata;
    }

    // This useEffect will only run once when the compone is mounted
    useEffect(()=>{
        setInterval(()=>{
            setContainerState(getTheTime());
        }, 10000);
    }, [])

    // This useEffect will run every time the component re-renders
    useEffect(() =>{
        console.log(getDisplayData())
    })

    // This useEffect will run every time the component is mounted
    useEffect(() =>{
        console.log("mounting the FCDisplayTimeInSameSpot");
    }, []);

    // This useEffect will run every time the component is unmounted
    useEffect(() =>{
        return ()=>console.log("unmounting the FCDisplayTimeInSameSpot");
    });

    return (
        <>
            <p>Time is - {getDisplayData()}</p>
        </>
    )
}

Drop this component as a child of any other component to see it work e.g.

Code Block
languagejs
import React from 'react';
import './App.css';
import FCDisplayTimeInSameSpot from './FCDisplayTimeInSameSpot';


function App() {
  const switchComponents = true;

  return (
    <div className="App">
      <header className="App-header">
        <FCDisplayTimeInSameSpot/>
      </header>
    </div>
  );
}

export default App;

Monitor the behaviour from the outputs in the browser’s console, you will notice the following

Event

What’s executed in order shown

Initial loading of the component

Notice that both these useEffects() witht the lambda and empty array are called once and only once

console.log("Executing FCDisplayTimeInSameSpot()");

Code Block
    // This useEffect will only run once when the component is first mounted
    useEffect(()=>{
        setInterval(()=>{
            setContainerState(getTheTime());
        }, 10000);
    }, [])

    // This useEffect will only run once when the component is first mounted
    useEffect(() =>{
        console.log("mounting the FCDisplayTimeInSameSpot");
    }, []);

Component needs to be re-rendered

Notice that the component method is first called, then it is unmounted, then is finally re-rendered through the component return() block (you can see this because the useEffect() with only the lambda is called

console.log("Executing FCDisplayTimeInSameSpot()");

Code Block
    // This useEffect will run every time the component is unmounted
    useEffect(() =>{
        return ()=>console.log("unmounting the FCDisplayTimeInSameSpot");
    });
Code Block
   // This useEffect will run every time the component re-renders
    useEffect(() =>{
        console.log(getDisplayData())
    })

Notice that the component method is always called