← Back to list

⚠️ This Small React Pattern Was Causing Flickers and Remounts in My Production Apps

Manjeet Singh · 2026-06-03 15:18 · 0 claps · 3.4 min read paywalled
#react-native #react #performance-optimization #react-native-performance #react-performance-hacks
Open on Medium ↗
Wiki topics: 🌐 · Web Development 📱 · Mobile Development

🔥🧨 This Small React Pattern Was Causing Flickers and Remounts in My Production Apps

A tiny React-Native pattern that looked harmless initially — until I started noticing unstable UI behavior across multiple real-world screens.

While working across multiple React Native production apps over the years, I occasionally encountered screens where certain UI sections felt… weirdly unstable.

Sometimes:

  • Images flickered while typing
  • Animations restarted unexpectedly
  • The internal component state got reset
  • loaders briefly reappeared
  • expensive UI sections kept rebuilding

Initially, I assumed these were caused by:

  • FlatList issues
  • memoization problems
  • image rendering glitches
  • React-Native bridge delays

🔓 Not a Medium member? ***Read here for free***

But after debugging several such issues across different apps, I noticed one surprisingly small pattern that kept appearing repeatedly:

Declaring components inside another component’s render function.

🤔 The Pattern That Looks Completely Fine

Initially, this pattern feels harmless.

const ParentComponent = () => {  
  const [input, setInput] = useState('');

  const SomeChildComponent = ({ value }) => {
      return <Text>{value}</Text>;
    };
    return (
      <>
        <TextInput
          value={input}
          onChangeText={setInput}
        />
        <SomeChildComponent value={input} />
      </>
    );
};

ddd

Honestly, I had observed code like this at multiple places across different apps earlier.

Small component → Simple logic → Feels readable → So what’s the issue?

🧠 The Real Problem Is NOT Re-rendering

Initially, I tried measuring render counts. And surprisingly, both nested and non-nested versions showed similar render logs. That confused me for quite some time.

Later, I realized:

The issue is not extra rendering. The issue is component remounting.

Every time ParentComponent re-renders, this line runs again:

const SomeChildComponent = () => {}

Which means React receives a completely new function reference every render.

Something like:

// Previous render
SomeChildComponent => function A
// Next render
SomeChildComponent => function B

For React:

A !== B

So React may treat it as:

  • old component removed
  • new component mounted

instead of:

  • same component updated

That subtle difference can create unnecessary UI work.

👀 How I Actually Verified This

At first, render logs alone were misleading.

So instead of checking only render counts, I started tracking mount and unmount behavior.

Something like this:

useEffect(() => {
  console.log('Component mounted');
  return () => {
    console.log('Component unmounted');
  };
}, []);

Then I tested the nested component version while typing inside a TextInput.

The logs started looking like this:

Component unmounted
Component mounted
Component unmounted
Component mounted

on almost every keystroke.

That’s when the flickering behavior finally started making sense.

The component was not just re-rendering. It was repeatedly destroyed and recreated.

📱 Real Problems This Can Cause in Apps

In small demo projects, you may barely notice this. But in larger React-Native production apps, this can become surprisingly expensive.

Especially if the nested child contains:

  • images
  • animations
  • videos
  • expensive calculations
  • hooks
  • internal state
  • API calls
  • FlatLists
  • gesture handlers

You might observe:

  • image flickers
  • animation resets
  • scroll position resets
  • unnecessary effect cleanup/recreation
  • keyboard jank
  • typing lag
  • lost internal state

And these issues become even more visible on lower-end Android devices.

✅ Better Approach

Instead of declaring the child inside the parent component, move it outside.

const SomeChildComponent = ({ value }) => {
  return <Text>{value}</Text>;
};

const ParentComponent = () => {
  const [input, setInput] = useState('');
  return (
    <>
      <TextInput
        value={input}
        onChangeText={setInput}
      />
      <SomeChildComponent value={input} />
    </>
  );
};

Now React sees the same stable component type on every render.

The child may still re-render when props change — which is completely normal — but React no longer unnecessarily destroys and recreates the entire subtree.

🤷‍♂️ What About Render Functions?

While experimenting, I also tested this pattern:

const renderChild = ({ value }) => {
  return <Text>{value}</Text>;
};

return renderChild({ value: input });

This actually behaved more stably than nested component declarations.

Why?

Because React only sees the final JSX output:

<Text />

and not a completely new component type.

But personally, I still prefer properly extracted components because they provide:

  • cleaner separation
  • better debugging
  • reusable UI
  • hooks support
  • easier optimization later

⚡ One Important Thing I Learned

This issue is easy to miss because:

  • Render counts can look normal
  • React.memo may not help
  • Everything may still “work.”
  • High-end devices often hide the problem

But once screens become large and interactive, these small patterns slowly compound.

And honestly, many React-Native performance issues are not caused by one giant mistake.

They usually come from:

  • small unnecessary remounts
  • unstable references
  • Repeated expensive work and
  • avoidable subtree recreations

accumulate over time.

✨ Final Thoughts

After noticing this pattern properly across multiple production apps, I started avoiding nested component declarations almost entirely in performance-sensitive screens.

Not because React completely breaks with them.

But because component identity stability matters much more than it initially appears.

Especially in React-Native apps, where:

  • The rendering cost is higher
  • animations matter
  • image loading matters
  • bridge/native work exists
  • Lower-end devices expose issues faster

It’s one of those tiny React patterns that looks innocent initially… but can quietly hurt performance over time.

rendering pattern bottlneck illustration in react

rendering pattern bottlneck illustration in react

Note: This article was lightly refined with the help of **Outlier**.


메타데이터
post_id
3bc68003eaac
slug
️-this-small-react-pattern-was-causing-flickers-and-remounts-in-my-production-apps-3bc68003eaac
url
https://medium.com/@singhmanjeetn/%EF%B8%8F-this-small-react-pattern-was-causing-flickers-and-remounts-in-my-production-apps-3bc68003eaac
canonical_url
https://medium.com/@singhmanjeetn/%EF%B8%8F-this-small-react-pattern-was-causing-flickers-and-remounts-in-my-production-apps-3bc68003eaac
author_url
https://medium.com/@singhmanjeetn
status
ok
fetched_at
2026-08-23 03:17:38