In this lesson, you will learn how to reuse core business logic while swapping specific native component implementations using the "Component Shadowing" pattern.
The Problem: Platform Divergence
In a large React Native project, you often have logic (like state management or data validation) that is identical across iOS, Android, and Web. However, the UI layer for these platforms often requires different native components. If you hard-code these differences throughout your components, your codebase becomes cluttered with messy if (Platform.OS === 'ios') checks.
The Shadowing Solution
Component shadowing is a strategy where you define a core interface for your component and create platform-specific "shadow" files that the bundler resolves based on the environment.
By using file extensions like .ios.tsx, .android.tsx, and .web.tsx, React Native automatically picks the file that matches the platform you are building for.
Implementation Example
Imagine you want a VideoPlayer component. The business logic (loading, buffering states) is the same, but the UI uses a different native player on each platform.
- Create a base file:
VideoPlayer.ts(This handles your logic/types). - Create platform-specific files:
VideoPlayer.ios.tsx(Importsreact-native-videoor custom Swift modules).VideoPlayer.android.tsx(Importsexoplayeror custom Kotlin modules).
Your folder looks like this:
components/
VideoPlayer/
VideoPlayer.ios.tsx
VideoPlayer.android.tsx
VideoPlayer.web.tsx
In your main application code, you simply import the component:
import { VideoPlayer } from './components/VideoPlayer';
You don't need to specify which file to pick. When you run npx react-native run-ios, the Metro bundler ignores the .android and .web files and "shadows" the core import with the iOS implementation.
This approach keeps your business logic clean and isolated, ensuring your main application components stay focused on features rather than fighting platform-specific native dependencies. It creates a "single source of truth" for logic while allowing the UI to remain perfectly native for every device.
Key Takeaway: Component Shadowing uses platform-specific file extensions to allow you to share core logic while automatically swapping native implementations at build time.