React Post Tag - TechOpt.io https://www.techopt.io/tag/react Programming, servers, Linux, Windows, macOS & more Sat, 12 Jul 2025 21:40:27 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 https://www.techopt.io/wp-content/uploads/2024/07/cropped-logo-1-32x32.png React Post Tag - TechOpt.io https://www.techopt.io/tag/react 32 32 Solving Next.js dynamic() Flicker with React.lazy https://www.techopt.io/programming/solving-next-js-dynamic-flicker-with-react-lazy https://www.techopt.io/programming/solving-next-js-dynamic-flicker-with-react-lazy#respond Sat, 12 Jul 2025 21:40:24 +0000 https://www.techopt.io/?p=1039 If you’re working with the Next.js App Router and using the dynamic() function for component-level code splitting, you may have encountered an annoying issue: flickering during rendering of a conditionally-rendered dynamic component. Unfortunately, this is a known issue with the App Router and the dynamic function in Next.js. This behavior can degrade user experience, so […]

The post Solving Next.js dynamic() Flicker with React.lazy appeared first on TechOpt.

]]>
If you’re working with the Next.js App Router and using the dynamic() function for component-level code splitting, you may have encountered an annoying issue: flickering during rendering of a conditionally-rendered dynamic component. Unfortunately, this is a known issue with the App Router and the dynamic function in Next.js. This behavior can degrade user experience, so solving the Next.js dynamic flicker on your website is crucial.

In this post, I’ll break down:

  • Why next/dynamic causes flickering
  • Why it’s worse with nested dynamic components
  • When dynamic() is still safe to use
  • A practical alternative using React.lazy() and Suspense
  • What trade-offs to expect when switching

The Flickering Problem in Next.js

Using dynamic() from next/dynamic is a great way to lazy-load components and reduce your JavaScript bundle size. It also supports options like { ssr: false } to only load components on the client side.

However, when you use these components with the App Router, they often cause a flash of missing or unstyled content, especially during fast navigation or when conditionally rendering dynamic components.

Nested dynamic() calls tend to amplify this issue. For example, a parent component conditionally loading a child via dynamic(), which in turn loads another sub-component dynamically, can make the flickering more severe.

This issue has been reported in GitHub issues and community threads, but a rock-solid fix hasn’t yet made it into the framework.

Interestingly, this flicker seems to affect nested dynamic components more than top-level ones. In my testing, first-level dynamically rendered components used directly in the page file rarely exhibit the issue, which means it’s generally safe to use next/dynamic there to avoid flash of unstyled content (FOUC) during initial mount.

The Better Alternative: React.lazy() + Suspense

One workaround that has proven effective is switching from next/dynamic to native React.lazy() with Suspense. This approach introduces fewer hydration inconsistencies and minimizes flickering, even with nested lazy-loaded components.

Use next/dynamic for components initially rendered on the page, and use React.lazy() for nested components that are rendered conditionally inside those components.

Example 1: Top-level safe usage with next/dynamic

import dynamic from 'next/dynamic';
import { isSignedInAsync } from '../auth';

const PageShell = dynamic(() => import('../components/PageShell'));

export default async function Home() {
  const isSignedIn = await isSignedInAsync();

  if (isSignedIn) return null;

  return <PageShell />;
}

In this example, PageShell is conditionally rendered on the server using dynamic components. This is safe since the dynamic component is rendered with the initial HTML from the server.

Example 2: Nesting with React.lazy() and Suspense

"use client";
import dynamic from 'next/dynamic';

const NestedComponent = dynamic(() => import('./NestedComponent'));

export default function PageShell() {
  const [showNested, setShowNested] = useState(false);

  return (
    <div>
      <h1>Welcome</h1>
      <button onClick={() => setShowNested(true)}>Load Nested Component</button>
      {showNested && (
        <Suspense fallback={<div>Loading nested...</div>}>
          <NestedComponent />
        </Suspense>
      )}
    </div>
  );
}

We can safely use React.lazy() and Suspense inside our dynamically-rendered PageShell component to conditionally render our NestedComponent, and still benefit from lazy-loading and code-splitting.

If we try using the dynamic function instead of React.lazy here, we may get the Next.js dynamic flicker.

Trade-offs of Using React.lazy() Instead of dynamic

While React.lazy() and Suspense often result in smoother rendering, there are two notable downsides:

1. No Server-Side Rendering

Unlike next/dynamic, which lets you disable or enable SSR, React.lazy() only supports client-side rendering. This might hurt SEO if your component needs to be visible to crawlers.

2. Flash of Unstyled Content (FOUC) on Mount

If you do try to use React.lazy() for SSR and use it in the server-rendered HTML, React.lazy() may cause a brief flash of unstyled content because the Next.js bundler doesn’t automatically include the styles for components loaded through React.lazy() in the server-rendered HTML. This limitation can lead to inconsistent rendering.

This is why it’s best to use next/dynamic for components that are visible in the server-rendered HTML, ensuring that styles and structure are present at first paint, while reserving React.lazy() for non-critical or nested components. Using next/dynamic in the initial server-rendered HTML does not seem to cause flickering.

Final Thoughts on Preventing the Next.js Dynamic Flicker

If you’re seeing flickering with next/dynamic and conditional rendering, especially in complex nested layouts, you’re not alone. While the Next.js team continues to evolve App Router, switching to React.lazy() and Suspense where you can may provide a smoother user experience at this time.

To summarize:

  • Use next/dynamic safely for top-level page components
  • Use React.lazy() for nested dynamic imports to reduce flicker

The post Solving Next.js dynamic() Flicker with React.lazy appeared first on TechOpt.

]]>
https://www.techopt.io/programming/solving-next-js-dynamic-flicker-with-react-lazy/feed 0
React Conditional Rendering: Logical AND vs Ternary Operator https://www.techopt.io/programming/react-conditional-rendering-logical-and-vs-ternary-operator https://www.techopt.io/programming/react-conditional-rendering-logical-and-vs-ternary-operator#respond Tue, 01 Apr 2025 22:30:57 +0000 https://www.techopt.io/?p=877 After building countless React and React Native components, I’ve run into one too many frustrating bugs caused by the logical AND (&&) operator used for conditional rendering in JSX. These issues are often subtle and hard to track down, so I’ve made it a rule: I don’t use logical AND for conditional rendering in JSX […]

The post React Conditional Rendering: Logical AND vs Ternary Operator appeared first on TechOpt.

]]>
After building countless React and React Native components, I’ve run into one too many frustrating bugs caused by the logical AND (&&) operator used for conditional rendering in JSX. These issues are often subtle and hard to track down, so I’ve made it a rule: I don’t use logical AND for conditional rendering in JSX anymore. Instead, I stick with the ternary (conditional) operator (in other words, shorthand “if” statement). It’s safer, clearer, and avoids nasty surprises.

The Problem with Logical AND for Conditional Rendering

Here’s a typical use case with logical AND:

{user.age && <Text>{`Age: ${user.age}`}</Text>}

You might expect this to only render the Text element if user.age is defined, or above 0 (since 0 is a falsy value in JavaScript).

But consider what happens if user.age is 0 (a valid, real-world age). We don’t want the <Text> element to get rendered in this case, and it doesn’t.

However, it creates a pretty unwanted side effect:

  • 0 && <Text>...</Text> evaluates to 0.
  • React will render the value 0 directly, essentially interpreting it as text instead of a boolean value!
    • In React Native, this is even worse: it will actually crash the entire application with an error about trying to render text outside of a <Text> component!

Example:

const user = { age: 0 };

return (
  <View>
    {user.age && <Text>{`Age: ${user.age}`}</Text>}
  </View>
);

What renders: Just 0. Not the <Text> element.

This happens because && doesn’t enforce a boolean context; it returns the first falsy value or the last truthy value. That means non-boolean values like 0 or "" can sneak through and show up unexpectedly. This can also crash your entire application in the case of React Native!

A Better Alternative: The Ternary Operator (Shorthand “if” Statements)

Instead, I use the ternary (conditional) operator, which makes the intent clearer and avoids rendering unwanted values:

{user.age ? <Text>{`Age: ${user.age}`}</Text> : null}

This guarantees that only a JSX element or null will be rendered; no accidental numbers or strings appearing in your layout.

Improved Example:

const user = { age: 0 };

return (
  <View>
    {user.age ? <Text>{`Age: ${user.age}`}</Text> : null}
  </View>
);

What renders: Nothing if age is undefined, null or 0, and the full Text block if it’s any other number.

Summary: Use the Ternary Operator for Conditional Rendering in React

While using && for conditional rendering may seem like a shortcut, it’s not always safe. This is especially true when your condition might evaluate to a falsy non-boolean like 0. From my experience, using the ternary operator leads to fewer bugs and a more predictable UI.

✅ Use:

condition ? <Component /> : null

🚫 Avoid:

condition && <Component />

When writing JSX in React or React Native, I choose clarity over cleverness. The ternary operator keeps my components clean and my debugging sessions short!

The post React Conditional Rendering: Logical AND vs Ternary Operator appeared first on TechOpt.

]]>
https://www.techopt.io/programming/react-conditional-rendering-logical-and-vs-ternary-operator/feed 0
App Center Alternatives for React Native Developers https://www.techopt.io/programming/app-center-alternatives-for-react-native-developers https://www.techopt.io/programming/app-center-alternatives-for-react-native-developers#respond Sun, 16 Mar 2025 02:47:39 +0000 https://www.techopt.io/?p=833 Microsoft’s decision to discontinue and sunset App Center has left many React Native developers searching for reliable alternatives. If you’ve been using App Center for building, testing, and distributing your apps, it’s time to explore new solutions. In this guide, we’ll break down the best App Center alternatives to help you keep your workflow efficient […]

The post App Center Alternatives for React Native Developers appeared first on TechOpt.

]]>
Microsoft’s decision to discontinue and sunset App Center has left many React Native developers searching for reliable alternatives. If you’ve been using App Center for building, testing, and distributing your apps, it’s time to explore new solutions. In this guide, we’ll break down the best App Center alternatives to help you keep your workflow efficient and uninterrupted.

Why Is App Center Being Discontinued?

App Center has been a go-to choice for mobile developers, providing CI/CD capabilities, automated testing, and distribution for iOS and Android apps. However, Microsoft has decided to sunset the platform, leaving teams to find replacement services that meet their needs. Therefore, selecting the right alternative is crucial. The key factors in choosing an alternative include build automation, real-device testing, seamless app distribution, and over-the-air (OTA) updates.

Best App Center Alternatives for React Native

1. EAS (Expo Application Services)

For teams using EAS, it provides an all-in-one solution for building, updating, and distributing React Native apps. As a result, it is one of the best alternatives to App Center, especially for projects already leveraging Expo.

  • Pros:
    • Seamless integration with Expo projects
    • No need for local machine setup
    • Cloud-based builds for iOS and Android
    • EAS Update serves as an alternative to CodePush, allowing for seamless OTA updates
  • Cons:
    • Primarily geared toward Expo-managed projects
    • Limited flexibility for bare React Native apps

2. Hot Updater (Self-Hosted CodePush Alternative)

If you relied on App Center for CodePush, a crucial feature for deploying over-the-air updates, you need a replacement. Fortunately, one of the best open-source alternatives is Hot Updater. This is my personal favourite CodePush replacement. It provides similar functionality while allowing you to self-host your own OTA update solution.

  • Pros:
    • Self-hosted, offering full control over updates
    • Supports both iOS and Android
    • Intuitive web console for managing versions
    • Plugin support for various storage providers (AWS S3, Supabase, etc.)
  • Cons:
    • Requires infrastructure setup and maintenance
    • Needs DevOps expertise for proper implementation

3. Bitrise

Bitrise is one of the most popular CI/CD platforms for mobile development. It offers cloud-based automation, supports React Native out of the box, and provides a flexible pipeline system for building, testing, and deploying apps. Consequently, many teams transitioning from App Center have found it to be a reliable alternative.

  • Pros:
    • Pre-configured workflows for React Native
    • Easy integration with GitHub, GitLab, and Bitbucket
    • Supports both iOS and Android
  • Cons:
    • Limited free-tier resources
    • Learning curve for advanced workflow customization

4. Codemagic

Codemagic is another excellent CI/CD tool that specializes in mobile development. It supports React Native projects and simplifies the build and deployment process with minimal configuration. Additionally, its user-friendly approach makes it a strong choice for teams looking for a quick transition.

  • Pros:
  • Cons:
    • Can get expensive for teams with heavy usage
    • Limited concurrent builds on the free plan

5. Firebase App Distribution

If your primary need is distributing pre-release versions of your app, Firebase App Distribution is a great alternative to App Center’s distribution feature. Moreover, it integrates well with other Firebase tools, making it an appealing choice for teams already using Firebase.

  • Pros:
    • Easy tester management
    • Integrates with Firebase Crashlytics for monitoring
    • Works for both iOS and Android
  • Cons:
    • No built-in CI/CD
    • Requires additional tools for automated builds

Choosing the Right App Center Alternative for Your React Native Project

The best App Center alternative depends on your specific needs:

As App Center sunsets, transitioning to a new platform early will help ensure a smooth workflow. Consequently, by selecting the right alternative, you can continue to build, test, distribute, and update your React Native apps with minimal disruption.

The post App Center Alternatives for React Native Developers appeared first on TechOpt.

]]>
https://www.techopt.io/programming/app-center-alternatives-for-react-native-developers/feed 0
Handle Edge-to-Edge in React Native Android 15 (API 35) https://www.techopt.io/programming/handling-edge-to-edge-react-native-android-15 https://www.techopt.io/programming/handling-edge-to-edge-react-native-android-15#respond Thu, 19 Dec 2024 18:54:00 +0000 https://www.techopt.io/?p=526 With the release of Android 15 (API 35) and React Native 0.76, edge-to-edge layouts have become the default for modern Android apps. This change emphasizes the importance of handling safe area insets properly. If you’ve relied on React Native’s SafeAreaView, you’ve likely discovered that it doesn’t work on Android, as it was only designed with […]

The post Handle Edge-to-Edge in React Native Android 15 (API 35) appeared first on TechOpt.

]]>
With the release of Android 15 (API 35) and React Native 0.76, edge-to-edge layouts have become the default for modern Android apps. This change emphasizes the importance of handling safe area insets properly. If you’ve relied on React Native’s SafeAreaView, you’ve likely discovered that it doesn’t work on Android, as it was only designed with iOS’s notch in mind. Thankfully, the react-native-safe-area-context library offers a cross-platform solution that supports both Android and iOS.

In this article, we’ll walk you through the steps to replace SafeAreaView with View and utilize react-native-safe-area-context to ensure your layouts adapt to safe area insets correctly on Android.

Steps to Adapting Layout for Edge-to-Edge in React Native Android 15 (API 35)

1. Install the react-native-safe-area-context Library

If you haven’t already, add the library to your project using either npm or Yarn:

npm install react-native-safe-area-context

or

yarn add react-native-safe-area-context

2. Wrap your App with SafeAreaProvider

Add the SafeAreaProvider component to the root of your app and provide initialWindowMetrics to improve performance and avoid layout jumps on startup.

You can retrieve initialWindowMetrics from react-native-safe-area-context.

import React from 'react';
import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context';
import MyApp from './MyApp';

const App = () => (
  <SafeAreaProvider initialMetrics={initialWindowMetrics}>
    <MyApp />
  </SafeAreaProvider>
);

export default App;

3. Use Safe Area Insets Padding on Outer Views to Push Content out of Screen Edge

You can get child content to push into the safe area away from the screen edges by using padding on the outermost view. You should use useSafeAreaInsets for functional components, and withSafeAreaInsets for class components.

Examples

Functional Component

Here’s how to use the useSafeAreaInsets hook in a functional component:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const MyFunctionalComponent: React.FC = () => {
  const insets = useSafeAreaInsets();

  return (
    <View
      style={{
        ...styles.container,
        paddingTop: insets.top,
        paddingBottom: insets.bottom,
        paddingLeft: insets.left,
        paddingRight: insets.right,
      }}
    >
      <Text>Hello, world!</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
});

export default MyFunctionalComponent;
Class Component

Here’s how to use the withSafeAreaInsets higher-order component (HOC) in a class component:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { withSafeAreaInsets, SafeAreaInsetsContext } from 'react-native-safe-area-context';

interface Props {
  insets: SafeAreaInsetsContext;
}

class MyClassComponent extends React.Component<Props> {
  render() {
    const { insets } = this.props;

    return (
      <View
        style={{
          ...styles.container,
          paddingTop: insets?.top,
          paddingBottom: insets?.bottom,
          paddingLeft: insets?.left,
          paddingRight: insets?.right,
        }}
      >
        <Text>Hello, world!</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
});

export default withSafeAreaInsets(MyClassComponent);

That’s it! You can also decide which sides (top, bottom, left and right) you want to apply padding to based on the design of your screen. If you’re not sure, applying it to all sides and seeing how the screen looks is best.

Remarks

  • While react-native-safe-area-context exports a SafeAreaView component, our experience indicates that it can also lead to screen jumping issues, especially on iOS. Therefore, it’s still better to use the useSafeAreaInsets hook for functional components or the withSafeAreaInsets HOC for class components.
  • Passing initialWindowMetrics to SafeAreaProvider ensures accurate safe area insets on app startup, preventing layout jumps caused by delayed inset calculations.
  • For testing, you’ll want to use an Android emulator or phone that supports edge-to-edge and is running at least Android 15 (API 35), such as the Google Pixel 8.
  • If you were previously using SafeAreaView from react-native for iOS, you should remove all instances of SafeAreaView from your code. You can cross-reference our iOS guide here.

The post Handle Edge-to-Edge in React Native Android 15 (API 35) appeared first on TechOpt.

]]>
https://www.techopt.io/programming/handling-edge-to-edge-react-native-android-15/feed 0
Fix Screen Jumping Using SafeAreaView in React Native https://www.techopt.io/programming/fix-screen-jumping-safeareaview-react-native https://www.techopt.io/programming/fix-screen-jumping-safeareaview-react-native#respond Sun, 15 Dec 2024 00:10:03 +0000 https://www.techopt.io/?p=515 Screen jumping or flickering on mount is a common frustration when using SafeAreaView in iOS with React Native, specifically on devices with a notch or Dynamic Island. As these features are becoming increasingly common and now represent the majority of devices sold, addressing this issue is critical to ensure a smooth user experience. This problem, […]

The post Fix Screen Jumping Using SafeAreaView in React Native appeared first on TechOpt.

]]>
Screen jumping or flickering on mount is a common frustration when using SafeAreaView in iOS with React Native, specifically on devices with a notch or Dynamic Island. As these features are becoming increasingly common and now represent the majority of devices sold, addressing this issue is critical to ensure a smooth user experience. This problem, often referred to as “jumping SafeAreaView,” can interrupt the smooth user experience your app should deliver.

Thankfully, there’s a straightforward solution: replace SafeAreaView from the react-native library with View and leverage the react-native-safe-area-context library to handle safe area insets in a more optimized way.

In this article, we will guide you on how to implement this fix using TypeScript or JavaScript for both functional and class components.

Why Does Jumping with SafeAreaView Occur?

The screen jumping issue with SafeAreaView happens because of its initial rendering behavior on iOS. It’s unable to consistently calculate safe area insets before the content mounts, causing a noticeable flicker.

The react-native-safe-area-context library optimizes this process under the hood, ensuring a smoother rendering experience regardless of the device.

Steps to Fixing Screen Jumping when using SafeAreaView

1. Install the react-native-safe-area-context Library

If you haven’t already, add the library to your project using either npm or Yarn:

npm install react-native-safe-area-context

or

yarn add react-native-safe-area-context

2. Wrap your App in SafeAreaProvider

Add the SafeAreaProvider component to the root of your app and provide initialWindowMetrics to improve performance and avoid layout jumps on startup.

You can retrieve initialWindowMetrics from react-native-safe-area-context.

import React from 'react';
import { SafeAreaProvider, initialWindowMetrics } from 'react-native-safe-area-context';
import MyApp from './MyApp';

const App = () => (
  <SafeAreaProvider initialMetrics={initialWindowMetrics}>
    <MyApp />
  </SafeAreaProvider>
);

export default App;

3. Replace Instances of SafeAreaView with Padding Using Safe Area Insets

You should replace all instances of SafeAreaView throughout your application with insets using useSafeAreaInsets for functional components, or withSafeAreaInsets for class components.

Examples

Functional Component

Here’s how to use the useSafeAreaInsets hook in a functional component:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const MyFunctionalComponent: React.FC = () => {
  const insets = useSafeAreaInsets();

  return (
    <View
      style={{
        ...styles.container,
        paddingTop: insets.top,
        paddingBottom: insets.bottom,
        paddingLeft: insets.left,
        paddingRight: insets.right,
      }}
    >
      <Text>Hello, world!</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
});

export default MyFunctionalComponent;
Class Component

Here’s how to use the withSafeAreaInsets higher-order component (HOC) in a class component:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { withSafeAreaInsets, SafeAreaInsetsContext } from 'react-native-safe-area-context';

interface Props {
  insets: SafeAreaInsetsContext;
}

class MyClassComponent extends React.Component<Props> {
  render() {
    const { insets } = this.props;

    return (
      <View
        style={{
          ...styles.container,
          paddingTop: insets?.top,
          paddingBottom: insets?.bottom,
          paddingLeft: insets?.left,
          paddingRight: insets?.right,
        }}
      >
        <Text>Hello, world!</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
});

export default withSafeAreaInsets(MyClassComponent);

That’s it! You can also decide which sides (top, bottom, left and right) you want to apply padding to based on the design of your screen. If you’re not sure, applying it to all sides and seeing how the screen looks is best.

Remarks

  • While react-native-safe-area-context exports a SafeAreaView component, our experience indicates that it can also lead to screen jumping issues. For a robust and future-proof solution, use the useSafeAreaInsets hook for functional components or the withSafeAreaInsets HOC for class components.
  • Passing initialWindowMetrics to SafeAreaProvider ensures accurate safe area insets on app startup, preventing layout jumps caused by delayed inset calculations.
  • SafeAreaView is likely to be deprecated soon. With the introduction of edge-to-edge layouts on Android 15 (API 35) and React Native 0.76, the community is shifting toward react-native-safe-area-context for cross-platform consistency.
  • react-native-safe-area-context natively supports safe area insets on both iOS and Android, making it the ideal choice compared to SafeAreaView from react-native.

The post Fix Screen Jumping Using SafeAreaView in React Native appeared first on TechOpt.

]]>
https://www.techopt.io/programming/fix-screen-jumping-safeareaview-react-native/feed 0