0
useEffect(() => {
  // do something
}, [stringProp]);

stringProp is by default an empty string.

When I change stringProp to foobar the effect runs.

But,

the useEffect also runs when the component first mounts, which I don't want.

How to run an effect hook ONLY when props change?

GN.
  • 8,672
  • 10
  • 61
  • 126
  • 1
    looks like there's a good discussion of that [here](https://stackoverflow.com/questions/53253940/make-react-useeffect-hook-not-run-on-initial-render) – Seth Lutske Jul 07 '20 at 23:48

2 Answers2

1

I've solved this problem many times using a ref

const firstRun = useRef(true);
...
useEffect(() => {
  // skip the first run
  if (firstRun.current) {
    firstRun.current = false;
    return;
  }

  // do stuff
}, [stringProp]);
James
  • 80,725
  • 18
  • 167
  • 237
0

You can not stop useEffect run when the component first mounted, but you can do the condition checking to run your code inside it like this:

useEffect(() => {
  // Only run when stringProp has value, you might have different condition, add them there
  if(stringProp){
    // do something
  }
}, [stringProp]);

Updated: If you might set stringProp back to the initial value, you can do use useRef to control first time run like this

const isFirstTimeOfUseEffect = useRef(true)
useEffect(() => {
  // Only run when stringProp has value, you might have different condition, add them there
  if(!firstUseEffectRun.current){
    // do something
  }else{
    firstUseEffectRun.current = false
  }
}, [stringProp]);
Tony Nguyen
  • 3,298
  • 11
  • 19
  • the problem with this is that if `stringProp` is set back to an empty string at some point, the `do something` won't fire...so this is not a perfect solution – Seth Lutske Jul 07 '20 at 23:52
  • @SethLutske Thanks for your comment, I updated my answer to have better solution – Tony Nguyen Jul 08 '20 at 00:00