1

In am using React and trying to trigger a function only once, when the page initially loads. Currently, the below code triggers the console message twice at page load.

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

export default function TestRef(){

    const [inputValue, setInputValue] = useState("");
    const count = useRef(null);

    const myFunc = () => {
        console.log('Function Triggered');
    }

    useEffect(() => {
        if(!count.current){
            count.current = 1;
            myFunc();
        }
        return () => { count.current = null; }
      }, []);

    return (
    <>
      <p>Page content</p>
    </>
  );
}

I have read up on how React 18 intentionally double-renders elements, which is my reason for using useRef and for returning the cleanup function in the useEffect hook, but it still doesn't seem to work.

Ben S
  • 1,407
  • 1
  • 13
  • 27
  • `I have read up on how React 18 intentionally double-renders elements` Not just that, it also simulates unmounting and remounting components. If your component remounts, the effect will run again. Are you sure you want to make it so this effect does not run if the component remounts? – Nicholas Tower Oct 18 '22 at 14:52
  • Believe this answers your question: https://stackoverflow.com/a/71982736/15342707 – PiratePie Oct 18 '22 at 14:57
  • @NicholasTower for this particular use case, I do need to only run the effect once, on initial page load. I am trying to incorporate Editor.js into my app, but the editor was rendering twice and nothing I was doing seemed to work. – Ben S Oct 18 '22 at 23:15
  • Does this answer your question? [useEffect is running twice on mount in React](https://stackoverflow.com/questions/72238175/useeffect-is-running-twice-on-mount-in-react) – Youssouf Oumar Nov 22 '22 at 20:07

2 Answers2

0

hi please make sure you didn't invoke TestRef componenet twice in your page!

for debug and find rerenders you can use react profiler extention on chrome then remove extra rerender by using momo and useMemo and useCallback

Mohamad Ahmadi
  • 248
  • 2
  • 7
0

Finally got it to work by doing this. This appears to only run myFunc() once, on the initial rendering of the component.

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

export default function TestRef(){

    const [inputValue, setInputValue] = useState("");
    const count = useRef(null);

    const myFunc = () => {
        console.log('Function Triggered');
    }

    useEffect(() => {
        if(count.current == null){
            myFunc();
        }
        return () => { count.current = 1; }
      }, []);

    return (
    <>
      <p>Page content</p>
    </>
  );
}

Ben S
  • 1,407
  • 1
  • 13
  • 27