Advanced Interview Questions


Advanced Interview Questions Interview with follow-up questions

1. Can you explain how to use Redux in a React Native application?

In 2026 you use Redux Toolkit (RTK), the official, recommended way to write Redux. Plain createStore, hand-written action types, and combineReducers boilerplate are deprecated, so an interviewer expects RTK, not legacy Redux.

The flow:

  1. Install: npm install @reduxjs/toolkit react-redux

  2. Create a slice with createSlice (it generates the reducer and action creators, and lets you write "mutating" logic safely via Immer):

   import { createSlice } from '@reduxjs/toolkit';

   const counterSlice = createSlice({
     name: 'counter',
     initialState: { value: 0 },
     reducers: {
       increment: (state) => { state.value += 1; },
       addBy: (state, action) => { state.value += action.payload; },
     },
   });
   export const { increment, addBy } = counterSlice.actions;
   export default counterSlice.reducer;
  1. Configure the store and wrap the app:
   import { configureStore } from '@reduxjs/toolkit';
   import { Provider } from 'react-redux';
   import counterReducer from './counterSlice';

   const store = configureStore({ reducer: { counter: counterReducer } });

   const App = () => (

   );
  1. In components, read with useSelector and dispatch with useDispatch:
   const value = useSelector((s) => s.counter.value);
   const dispatch = useDispatch();
   dispatch(increment());

Follow-ups: use createAsyncThunk for async logic, RTK Query for data fetching/caching (often replacing hand-written thunks), and memoized selectors to avoid unnecessary re-renders. For lighter needs, Context or Zustand may be a better fit than Redux at all.

↑ Back to top

Follow-up 1

How would you handle asynchronous actions in Redux?

To handle asynchronous actions in Redux, you can use middleware like redux-thunk or redux-saga.

  1. Using redux-thunk: redux-thunk is a middleware that allows you to write action creators that return a function instead of an action. This function can then dispatch multiple actions, including asynchronous ones. Here's an example:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(rootReducer, applyMiddleware(thunk));

export default store;
  1. Using redux-saga: redux-saga is a middleware that uses generator functions to handle asynchronous actions. It provides a more powerful and flexible way to handle side effects. Here's an example:
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));

sagaMiddleware.run(rootSaga);

export default store;

Follow-up 2

What is the role of a reducer in Redux?

The role of a reducer in Redux is to specify how the application's state changes in response to actions. A reducer is a pure function that takes the current state and an action as arguments, and returns a new state. It should not modify the existing state, but instead create a new state object.

Here's an example of a reducer:

const initialState = {
  count: 0
};

const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    case 'DECREMENT':
      return { ...state, count: state.count - 1 };
    default:
      return state;
  }
};

export default counterReducer;

Follow-up 3

Can you explain the concept of 'store' in Redux?

In Redux, a store is an object that holds the state of your application. It is the single source of truth for your application's state. The store is created using the createStore function from the Redux package.

The store has the following responsibilities:

  • Holds the application state
  • Allows access to the state via the getState method
  • Allows state to be updated via the dispatch method
  • Registers listeners via the subscribe method

Here's an example of creating a store in Redux:

import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(rootReducer);

export default store;

Follow-up 4

What are some common middleware used in Redux?

Some common middleware used in Redux are:

  1. redux-thunk: redux-thunk is a middleware that allows you to write action creators that return a function instead of an action. This function can then dispatch multiple actions, including asynchronous ones.

  2. redux-saga: redux-saga is a middleware that uses generator functions to handle asynchronous actions. It provides a more powerful and flexible way to handle side effects.

  3. redux-logger: redux-logger is a middleware that logs the previous state, the action, and the next state to the console. It is useful for debugging and understanding how the state changes.

  4. redux-persist: redux-persist is a middleware that allows you to persist the Redux store to storage, such as localStorage or AsyncStorage. It is commonly used for handling app state persistence.

These are just a few examples of the many middleware available for Redux.

2. What is the Virtual DOM in React Native and how does it improve performance?

First, an important correction interviewers like to hear: React Native has no browser DOM, so the web "Virtual DOM" framing is imprecise. What React actually maintains is an in-memory tree of React elements describing the UI.

How it works in RN:

  1. When state or props change, React builds a new element tree and reconciles it against the previous one (the diffing algorithm), computing the minimal set of changes.

  2. Those changes are then committed to real native views. Under the New Architecture (default since 0.76, the only architecture since 0.82), React's Fabric renderer builds a C++ "shadow tree," and updates are applied directly to native UIKit/Android views over the JSI (JavaScript Interface) — synchronously and without the old serialized JSON "bridge."

Why it improves performance: instead of imperatively rebuilding native UI on every change, React figures out only what changed and commits just those mutations. Stable list keys let reconciliation match elements correctly so it can move/reuse views rather than recreate them.

So the accurate statement is: React reconciles an element tree (not a Virtual DOM clone of an HTML DOM), and Fabric commits the diff to native views via JSI. The benefit — minimal, batched UI updates — is the same idea as the web, but the target and mechanism differ.

↑ Back to top

Follow-up 1

What is the difference between the real DOM and the Virtual DOM?

The real DOM is the actual representation of the HTML structure of a web page. It is a tree-like structure that represents the UI components and their properties. Any changes made to the real DOM directly affect the web page and can be expensive in terms of performance. On the other hand, the Virtual DOM is a lightweight copy of the real DOM that is stored in memory. It is a representation of the UI components and their current state. React Native uses the Virtual DOM to optimize the rendering process by comparing it with the previous Virtual DOM and determining the minimal set of changes needed to update the real DOM.

Follow-up 2

How does React Native decide when to update the real DOM?

React Native uses a diffing algorithm to compare the previous Virtual DOM with the new one. It identifies the differences between the two and determines the minimal set of changes needed to update the real DOM. This process is called reconciliation. React Native updates the real DOM only for the components that have changed, instead of re-rendering the entire UI. This selective update approach helps in improving performance.

Follow-up 3

Can you explain the process of reconciliation in React Native?

Reconciliation is the process in React Native where the previous Virtual DOM is compared with the new one to determine the minimal set of changes needed to update the real DOM. It involves three main steps:

  1. Diffing: React Native performs a diffing algorithm to identify the differences between the previous Virtual DOM and the new one. It compares the UI components and their properties to determine which components have changed.

  2. Re-rendering: React Native re-renders only the components that have changed, instead of re-rendering the entire UI. This selective update approach helps in improving performance.

  3. Updating the real DOM: React Native updates the real DOM with the changes identified during the diffing process. Only the necessary changes are made to the real DOM, reducing the number of direct manipulations and improving performance.

3. How do you integrate Firebase with a React Native application?

For a React Native app, the standard choice is @react-native-firebase (Invertase), which wraps the native Firebase SDKs — preferred over the Firebase JS SDK when you need native-only features (analytics, Crashlytics, native performance). Use the modular API (v22+); the old namespaced API (firebase.auth().signIn(...)) is deprecated.

Steps:

  1. Create a Firebase project in the console and register your iOS/Android apps; download GoogleService-Info.plist and google-services.json.

  2. Install the app module plus the services you need:

   npm install @react-native-firebase/app @react-native-firebase/auth @react-native-firebase/firestore
  1. Expo: add the config plugins in app.json and point to the credential files, then build with EAS (this won't run in Expo Go — it needs a dev build). Bare RN: native config is handled by the plugins/autolinking.

  2. Use the modular functions:

   import { getApp } from '@react-native-firebase/app';
   import { getAuth, signInAnonymously } from '@react-native-firebase/auth';
   import { getFirestore, collection, getDocs } from '@react-native-firebase/firestore';

   const auth = getAuth();
   await signInAnonymously(auth);

   const db = getFirestore();
   const snap = await getDocs(collection(db, 'users'));

Notes: Firestore is preferred over the older Realtime Database for new apps. The original snippet used the web firebase/app package with a manual firebaseConfig and the deprecated chained API — outdated for a native RN app; mention native config files and modular imports instead.

↑ Back to top

Follow-up 1

What are some of the features provided by Firebase that can be used in a React Native application?

Firebase provides several features that can be used in a React Native application, including:

  1. Realtime Database: Firebase's realtime database allows you to store and sync data in real-time across multiple clients.

  2. Authentication: Firebase provides authentication services, allowing you to easily implement user authentication and authorization in your React Native application.

  3. Cloud Firestore: Firebase's Cloud Firestore is a flexible, scalable NoSQL database that allows you to store and sync data between clients and the cloud.

  4. Cloud Messaging: Firebase Cloud Messaging enables you to send push notifications to your React Native application's users.

  5. Storage: Firebase Storage provides secure file uploads and downloads for your React Native application.

These are just a few examples of the features provided by Firebase that can be used in a React Native application.

Follow-up 2

Can you explain how to handle user authentication using Firebase?

To handle user authentication using Firebase in a React Native application, you can follow these steps:

  1. Set up Firebase authentication by enabling the desired authentication providers (e.g., email/password, Google, Facebook) in the Firebase console.

  2. Install the necessary Firebase authentication packages using npm or yarn.

  3. Import the Firebase authentication module in your React Native application and initialize it with your Firebase project's configuration details.

  4. Use the Firebase authentication module's APIs to implement the desired authentication functionality, such as signing up, signing in, and signing out users.

Here is an example of how to handle user authentication using Firebase in a React Native application:

import firebase from 'firebase/app';
import 'firebase/auth';

// Initialize Firebase authentication
firebase.initializeApp(firebaseConfig);
const auth = firebase.auth();

// Sign up a new user
auth.createUserWithEmailAndPassword(email, password)
  .then((userCredential) => {
    // Handle successful sign up
  })
  .catch((error) => {
    // Handle sign up error
  });

// Sign in an existing user
auth.signInWithEmailAndPassword(email, password)
  .then((userCredential) => {
    // Handle successful sign in
  })
  .catch((error) => {
    // Handle sign in error
  });

// Sign out the current user
auth.signOut()
  .then(() => {
    // Handle successful sign out
  })
  .catch((error) => {
    // Handle sign out error
  });

Follow-up 3

How would you store and retrieve data using Firebase?

To store and retrieve data using Firebase in a React Native application, you can use Firebase's Realtime Database or Cloud Firestore.

  1. Realtime Database: To store and retrieve data using Firebase's Realtime Database, you can use the Firebase Realtime Database module and its APIs. You can store data as JSON-like objects and listen for real-time updates.

  2. Cloud Firestore: To store and retrieve data using Firebase's Cloud Firestore, you can use the Firebase Cloud Firestore module and its APIs. Cloud Firestore is a NoSQL database that allows you to store and sync data between clients and the cloud.

Here is an example of how to store and retrieve data using Firebase's Realtime Database in a React Native application:

import firebase from 'firebase/app';
import 'firebase/database';

// Initialize Firebase Realtime Database
firebase.initializeApp(firebaseConfig);
const database = firebase.database();

// Store data
database.ref('users/user1').set({
  name: 'John Doe',
  age: 25
});

// Retrieve data
database.ref('users/user1').once('value')
  .then((snapshot) => {
    const user = snapshot.val();
    // Handle retrieved data
  })
  .catch((error) => {
    // Handle retrieval error
  });

4. How do you implement animations in a React Native application?

React Native has two main animation paths, and the right answer in 2026 leads with the modern one:

Reanimated (v4) — the current standard for anything non-trivial. It runs animations on the UI thread using worklets (react-native-worklets), so they stay smooth at 60/120 fps even when the JS thread is busy. v4 requires the New Architecture and also adds a CSS-style animation API.

import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';

const offset = useSharedValue(0);
const style = useAnimatedStyle(() => ({ transform: [{ translateX: offset.value }] }));

// trigger: offset.value = withSpring(100);
return ;

Core Animated API — built in, still valid for simpler cases. The critical gotcha is to set useNativeDriver: true so the animation runs natively instead of being driven from JS frame-by-frame (note: the native driver supports transform/opacity, not layout props like width/height).

Animated.timing(opacity, { toValue: 1, duration: 300, useNativeDriver: true }).start();

Follow-ups: pair Reanimated with react-native-gesture-handler for gesture-driven animations, use LayoutAnimation for simple automatic layout transitions, and remember the headline principle — keep animation work off the JS thread (native driver / UI-thread worklets) to avoid dropped frames.

↑ Back to top

Follow-up 1

What are some of the libraries you can use to create animations in React Native?

There are several libraries available for creating animations in React Native. Some popular ones include:

  • react-native-animatable: This library provides a set of pre-defined animations that can be easily applied to components.

  • react-native-reanimated: This library is a high-performance animation library that allows you to create complex animations using a declarative API.

  • react-native-svg: This library allows you to create animated SVG components in React Native.

  • react-native-animatable-svg: This library combines the features of react-native-animatable and react-native-svg to provide animated SVG components with pre-defined animations.

Follow-up 2

Can you explain the difference between layout animations and animated API in React Native?

In React Native, layout animations and the Animated API are two different approaches to implementing animations.

  • Layout animations: Layout animations are automatic animations that are applied to the layout of components when their properties change. For example, when a component's height or width changes, React Native can automatically animate the transition.

  • Animated API: The Animated API is a more flexible and powerful way to create animations in React Native. It allows you to define animated values and use them to drive the animation of components. With the Animated API, you have full control over the animation and can animate various properties of components such as opacity, scale, position, and rotation.

Follow-up 3

How would you handle complex animations in React Native?

To handle complex animations in React Native, you can use the Animated API along with other libraries and techniques.

  • Animated API: The Animated API provides a powerful set of tools to create complex animations. You can use animated values, interpolation functions, and timing functions to create animations with multiple components and properties.

  • Layout animations: Layout animations can be used to automatically animate the layout of components when their properties change. This can be useful for simple animations that don't require fine-grained control.

  • Third-party libraries: There are several third-party libraries available that provide additional features and pre-defined animations. These libraries can help simplify the implementation of complex animations.

  • Native modules: In some cases, you may need to use native code to achieve complex animations. React Native allows you to create native modules that can be used to interact with native APIs and perform advanced animations.

5. What are some strategies you would use to optimize the performance of a React Native application?

Strategies to optimize a React Native app, framed as a diagnose-then-fix process:

  1. Profile first: Don't guess. Use React DevTools Profiler to find wasteful re-renders, Hermes sampling profiles for JS-thread hotspots, and the in-app perf monitor / Flipper-style tooling for frame drops. Optimize what the data shows.

  2. Cut unnecessary re-renders: React.memo components, stabilize props with useMemo/useCallback, avoid inline objects/functions in JSX, and use memoized selectors with Redux so a component re-renders only when its slice changes.

  3. Virtualize lists: Use FlatList/SectionList (or FlashList for very large/complex lists) instead of mapping inside a ScrollView. Provide stable keys via keyExtractor, and getItemLayout for fixed-height rows.

  4. Keep the JS thread free: Debounce/throttle expensive handlers, defer non-urgent work with InteractionManager, and memoize heavy computations.

  5. Optimize images and assets: Correctly sized, compressed, cached images (expo-image / react-native-fast-image); lazy-load screens with React.lazy/Suspense and dynamic import().

  6. Use the modern runtime: Hermes (default engine) plus the New Architecture (Fabric + TurboModules + JSI) — already the default since 0.76 — remove the legacy bridge bottleneck and speed up startup/rendering.

  7. Animate off the JS thread: Reanimated worklets or Animated with useNativeDriver: true for 60/120 fps.

Note the original answer's "Web Workers / Worker threads" and the standalone "Performance Monitor" framing are dated for RN — say InteractionManager/profiling tools instead. The key interview point: measure, fix the actual bottleneck, then re-measure.

↑ Back to top

Follow-up 1

Can you explain how to use the Profiler in React Native?

To use the Profiler in React Native, follow these steps:

  1. Import the Profiler component from the 'react' package: import { Profiler } from 'react';

  2. Wrap the component you want to profile with the Profiler component and provide a callback function to the 'onRender' prop. This callback function will be called whenever the component is rendered:




  1. Implement the callback function to collect performance measurements. The callback function receives the following parameters: id, phase, actualDuration, baseDuration, startTime, commitTime, interactions:
function callback(id, phase, actualDuration, baseDuration, startTime, commitTime, interactions) {
  // Collect performance measurements
}
  1. Use the collected performance measurements to analyze and optimize your app's performance.

Follow-up 2

What are some common performance issues in React Native and how would you mitigate them?

Some common performance issues in React Native include:

  1. Excessive re-renders: Components re-rendering too frequently can impact performance. To mitigate this, use shouldComponentUpdate or React.memo to prevent unnecessary re-renders.

  2. Large lists: Rendering large lists can cause performance issues. Use FlatList or VirtualizedList instead of ScrollView to only render the items that are currently visible on the screen.

  3. Inefficient image loading: Loading large or improperly sized images can slow down your app. Optimize images by compressing them and using the appropriate size.

  4. Blocking the main thread: Performing heavy calculations or data processing on the main thread can cause the app to become unresponsive. Use Web Workers or Worker threads to offload these tasks to a separate thread.

  5. Inefficient data fetching: Inefficient data fetching can impact performance. Use pagination or infinite scrolling to fetch data in smaller chunks instead of loading all data at once.

  6. Unoptimized animations: Animations that are not properly optimized can cause performance issues. Use Animated API or third-party libraries like react-native-reanimated for smoother and more performant animations.

To mitigate these performance issues, follow the strategies mentioned earlier, such as minimizing renders, optimizing images, using native modules, and profiling your app.

Follow-up 3

How does using a Virtual DOM help in performance optimization?

Using a Virtual DOM helps in performance optimization in the following ways:

  1. Efficient updates: The Virtual DOM allows React to perform efficient updates by comparing the current Virtual DOM tree with the previous one. Only the differences between the two trees are updated in the actual DOM, reducing the number of DOM manipulations.

  2. Batched updates: React batches multiple updates together and performs them in a single batch, minimizing the number of DOM operations and improving performance.

  3. Optimized rendering: React uses a diffing algorithm to determine the minimal set of changes needed to update the DOM. This optimized rendering process reduces the overall computational cost and improves performance.

  4. Reconciliation: The Virtual DOM reconciles the current state of the UI with the desired state, ensuring that only the necessary updates are applied to the DOM. This helps in avoiding unnecessary re-renders and improving performance.

Overall, using a Virtual DOM allows React to efficiently update the DOM, batch updates, optimize rendering, and reconcile the UI state, resulting in improved performance for React Native applications.

Live mock interview

Mock interview: Advanced Interview Questions

Intermediate ~5 min Your own free AI key

Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.