DEV Community

Cover image for The Rogue React Component
Abraham Toledo
Abraham Toledo

Posted on

The Rogue React Component

The Issue at Hand

Let's dive right in: imagine (or try to 😉) you're having a nice afternoon writing a code snippet that employs an external component we'll conveniently call RogueComp:

const MyComp = ({ someVariableProp }) => {
  return (
    <>
    ... Some markup
      <RogueComp someProp={someVariableProp} /> 
    ...
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

You start testing, everything seems fine, but alas, the RogueComp has taken matters into its own hands and decided to disregard any changes in the props. The likely cause? RogueComp probably uses someProp to set up its internal state, which means it's unresponsive to any subsequent prop changes.

Here's a simplified view of what's probably happening under the hood:

const RogueComp = ({ someProp }) => {
  const [someState, setSomeState] = useState(someProp);

  return <p>{someState}</p>;
};
Enter fullscreen mode Exit fullscreen mode

Before you start pointing fingers, I'm not the one responsible for this mischievous component!

The Fred Flintstone Solution

Unable to make it work right, you devise a clever plan: grab our stick and smash RogueComp to the ground and then bring it back to life.

You concoct the following strategy:

const MyComp = ({ someVariableProp }) => {
+  const [invalid, setInvalid] = useState(false);
+
+  const invalidate = () => {
+    setInvalid(true);
+    setTimeout(() => setInvalid(false));
+  };
+
+  useEffect(() => {
+    invalidate();
+  }, [someVariableProp]);

  return (
    <>
    ... Some markup
+      {!invalid ? 
        <RogueComp someProp={someVariableProp} /> 
+        : null
+      }
    ...
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

Voila! It works like a charm, saving the day. Yaba-daba-dooo!

... Not so fast.

A surprise hitch appears – RogueComponent acquired quantum powers and every time someProp changes, it briefly disappears. Why? Because it's not smoothly rendered in one go.

The Right Approach

Hold tight, because there's another way out: the mighty React's key prop comes to the rescue. Yup, key is not just an obscure list's concept. Think of it as a signal to React that a particular section of the DOM needs a complete overhaul. Here's the gist from the React docs:

You can reset a component’s state by passing a different key to a component. (...) When the key changes, React re-creates the (...) component (and all of its children) from scratch, so its state gets reset.

Let's tackle this head-on:

const MyComp = ({ someVariableProp }) => {
+  const freshKey = useMemo(() => `${Math.random()}`, [someVariableProp]);

  return (
    <>
    ... Some markup
-      <RogueComp someProp={someVariableProp}
+      <RogueComp key={freshKey} someProp={someVariableProp} />
    ...
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

See how this solution is not just smoother and simpler, but also eradicates the pesky flickering issue? No more awkward gaps in the rendering process.

Another job well done! 😄

Top comments (0)