DEV Community

Fatemeh Paghar
Fatemeh Paghar

Posted on

React useEffect only on Update

Have you ever thought what is the best way to run Redact’s useEffect Hook only on updates? Have you ever considered Redact’s useRef Hook as a solution to create an instance variable and track the lifecycle of a component?

We can define a ref variable in the functional component in React when It is necessary to keep tracking some state without using React’s re-render mechanism. illustration, we can determine if a component was rendered for the first time or if it was re-rendered. First, consider the following example:

const UseEffectUpdates = () => {

    const[ txtValue, setTxtValue] = useState({
        value1:"",
        value2:""
    })
    const [txtColor, setTxtColor] = useState("white");

    const [toggle, setToggle] = useState(true);
    const didMount = useRef(false);
    const handleToggle = () => {
        setToggle(!toggle);
    };

    const txtChange1 = (event)=>{
        event.preventDefault();
        console.log("textbox change 1");
        setTxtValue({...txtValue, value1:event.target.value});
        if (txtValue.value2 ===  event.target.value){
            setTxtColor("green");
        }
    }

    const txtChange2 = (event)=>{
        event.preventDefault();
        console.log("textbox change 2");
        setTxtValue({...txtValue, value2:event.target.value})
        if(txtValue.value1 === event.target.value){
            setTxtColor("green")
        }
    }

    useEffect(() => {
        if (didMount.current) {
        console.log('I run only if toggle changes.');
        } else {
        didMount.current = true;
        }
    }, [toggle]);

    return (
        <div>
            <input style={{backgroundColor:txtColor}} type="text"  placeholder="name1" onChange={txtChange1}  value={txtValue.value1}/>
            <br/>
            <input style={{backgroundColor:txtColor}} type="text"  placeholder="name2" onChange={txtChange2}  value={txtValue.value2}/>
            <br/>
            <button type="button" onClick={handleToggle}>
                Toggle
            </button>        
        </div>
    );
};

Enter fullscreen mode Exit fullscreen mode

In the above sample code, the didMount variable is initialized with true, because it is supposed to be the component rendered the first time when it gets initialized. Also using the useEffect hook with toggle dependency to update the ref’s current property(didMount) after the first render of the component. When the didMount is false, it doesn’t trigger a re-render thought.When you run the above code, the useEffect just runs when clicking on the toggle button, and the handleToggle event runs. On the other hand, when the textboxes are changed the useEffect doesn’t run.

That is all. If you want to keep track of the state in your React component which shouldn't cause it to re-render, React's useRef Hooks is an option to create an instance variable for it.

Oldest comments (5)

Collapse
 
saharb86 profile image
saharb

this post helped me much🙏🏻

Collapse
 
mortezasabihi profile image
Morteza Sabihi

Helpful tip, continue writing :)

Collapse
 
iman_40 profile image
Iman

Das war total Hilfreich

Collapse
 
farzadjamshidi profile image
farzadjamshidi

I always think about why we migrate from class components to function components? I like class components more :D

Collapse
 
fpaghar profile image
Fatemeh Paghar

Reasons as follows to use:

1) Functional components are much easier to read and test because they
are plain JavaScript functions without state or lifecycle hooks.

2) You end up with less code.

3)It will get easier to separate container and presentational components because you need to think more about your component’s state if you don’t have access to setState() in your component.

4)The React team mentioned that there may be a performance boost for a functional component in future React versions

5)There is one difference is the syntax. A functional component is just a plain JavaScript function that accepts props as an argument and returns a React element. A class component requires you to extend from React.Component and create a render function that returns a React element. This requires more code but will also give some benefits.