Currently, the popular React Native framework is Expo, which provides the Expo Modules API for us to quickly develop a Native component or module.
This article will briefly introduce how to initialize and write a simple Native component in Expo ~52 within the current project.
Preparation#
Before starting, make sure you have created an Expo project.
Then, create an Expo Module using the following command.
npx create-expo-module@latest --local
Follow the prompts to create a Module. It is located under modules/<name>
and contains the following files.
.
├── android
│ ├── build.gradle
│ └── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── expo
│ └── modules
│ └── testmodule
│ ├── TestModule.kt
│ └── TestModuleView.kt
├── expo-module.config.json
├── index.ts
├── ios
│ ├── TestModule.podspec
│ ├── TestModule.swift
│ └── TestModuleView.swift
└── src
├── TestModule.ts
├── TestModule.types.ts
├── TestModule.web.ts
├── TestModuleView.tsx
└── TestModuleView.web.tsx
10 directories, 14 files
Among them, the android and ios directories are the entry points for writing native code.
Integrating into an Existing Project#
Now we need to apply this module to the current app.
Edit package.json
to add this field:
"expo": {
"autolinking": {
"nativeModulesDir": "./modules"
}
},
Then, run npm run expo prebuild --clean
to refresh the iOS and Android projects.
After the native dependencies are installed, we open the xcworkspace file using Xcode.
Writing a Simple Module#
An official example module already exists in the initial template. We can also try writing a simple component ourselves. Below is an example written for the iOS platform using Swift UI.
Find our module location as shown in the image.
Create a new internal module and organize the files as follows:
../ListView
├── ListView.swift
└── ListViewModule.swift
In ListView.swift
, write the following code for a simple SwiftUI List:
import SwiftUI
struct ListView: View {
var body: some View {
List {
ForEach(1...10, id: \.self) { index in
Text("\(index)")
}
}
}
}
#Preview {
ListView()
}
Then define the Expo Module by editing ListViewModule.swift
import ExpoModulesCore
import SwiftUI
class ListViewProps: ExpoSwiftUI.ViewProps {
}
fileprivate struct ListViewExpoView: ExpoSwiftUI.View {
@EnvironmentObject var props: ListViewProps
var body: some View {
ListView()
}
}
public class ListViewModule: Module {
public func definition() -> ModuleDefinition {
Name("ListView") // Identifier used for calling requireNativeView later
View(ListViewExpoView.self) // Use ListViewExpoView
}
}
At this point, the native side is complete. Next, modify expo-module.config.json
Add the newly added ListViewModule
.
{
"platforms": [
"apple",
"android",
"web"
],
"apple": {
"modules": [
"TestModule",
"ListViewModule" // Added
]
},
"android": {
"modules": [
"expo.modules.testmodule.TestModule"
]
}
}
Since we haven't implemented Android, we won't write it here. Then execute npm expo prebuild
.
Using Native Components in React Native#
After the above steps, we can use it in React Native like this.
import { requireNativeView } from 'expo'
import type { ViewProps } from 'react-native'
interface ListViewProps extends ViewProps {}
const ListView = requireNativeView<ListViewProps>('ListView') // Use the Name defined above
export default function HomeScreen() {
return <ListView style={{ flex: 1 }} />
}
Then start the project in Xcode while also starting the metro dev server
.
Through Xcode View Hierarchy, we can see that the NativeView has rendered correctly.
This article is synchronized and updated to xLog by Mix Space. The original link is https://innei.in/posts/tech/use-native-components-in-expo