创建模态
在本教程中,了解如何创建 React Native 模式来选择图片。
React Native 提供了 <Modal>
组件,将内容渲染在应用的其余部分之上。一般来说,模态框用于吸引用户对关键信息的注意或指导他们采取行动。例如,在 第三章 中,按下按钮后,我们使用 alert()
显示一些占位符文本。这就是模态组件显示叠加层的方式。
¥React Native provides a <Modal>
component that presents content above the rest of your app. In general, modals are used to draw a user's attention toward critical information or guide them to take action. For example, in the third chapter, after pressing the button, we used alert()
to display some placeholder text. That's how a modal component displays an overlay.
在本章中,我们将创建一个显示表情符号选择器列表的模式。
¥In this chapter, we'll create a modal that shows an emoji picker list.

1
Declare a state variable to show buttons
Before implementing the modal, we are going to add three new buttons. These buttons are visible after the user picks an image from the media library or uses the placeholder image. One of these buttons will trigger the emoji picker modal.
In app/(tabs)/index.tsx:
- Declare a boolean state variable,
showAppOptions
, to show or hide the buttons that open the modal, alongside a few other options. When the app screen loads, we'll set it tofalse
so the options are not shown before picking an image. When the user picks an image or uses the placeholder image, we'll set it totrue
. - Update the
pickImageAsync()
function to set the value ofshowAppOptions
totrue
after the user picks an image. - Update the button with no theme by adding an
onPress
prop with the following value.
!!!IG11!!!
!!!IG0!!!
In the above snippet, we're rendering the Button
component based on the value of showAppOptions
and moving the buttons in the ternary operator block. When the value of showAppOptions
is true
, render an empty <View>
component. We'll address this state in the next step.
Now, we can remove the alert
on the Button
component and update the onPress
prop when rendering the second button in the components/Button.tsx:
!!!IG12!!!
!!!IG1!!!
2
Add buttons
Let's break down the layout of the option buttons we'll implement in this chapter. The design looks like this:
It contains a parent <View>
with three buttons aligned in a row. The button in the middle with the plus icon (+) will open the modal and is styled differently than the other two buttons.
Inside the components directory, create a new CircleButton.tsx file with the following code:
!!!IG2!!!
To render the plus icon, this button uses the <MaterialIcons>
icon set from the @expo/vector-icons
library.
The other two buttons also use <MaterialIcons>
to display vertically aligned text labels and icons. Create a file named IconButton.tsx inside the components directory. This component accepts three props:
icon
: the name corresponding to theMaterialIcons
library icon.label
: the text label displayed on the button.onPress
: this function invokes when the user presses the button.
!!!IG3!!!
Inside app/(tabs)/index.tsx:
- Import the
CircleButton
andIconButton
components to display them. - Add three placeholder functions for these buttons. The
onReset()
function invokes when the user presses the reset button, causing the image picker button to appear again. We'll add the functionality for the other two functions later.
!!!IG13!!!
!!!IG4!!!
Let's take a look at our app on Android, iOS and the web:
3
Create an emoji picker modal
The modal allows the user to choose an emoji from a list of available emoji. Create an EmojiPicker.tsx file inside the components directory. This component accepts three props:
isVisible
: a boolean to determine the state of the modal's visibility.onClose
: a function to close the modal.children
: used later to display a list of emoji.
!!!IG14!!!
!!!IG5!!!
Let's learn what the above code does:
- The
<Modal>
component displays a title and a close button. - Its
visible
prop takes the value ofisVisible
and controls whether the modal is open or closed. - Its
transparent
prop is a boolean value, which determines whether the modal fills the entire view. - Its
animationType
prop determines how it enters and leaves the screen. In this case, it is sliding from the bottom of the screen. - Lastly, the
<EmojiPicker>
invokes theonClose
prop when the user presses the close<Pressable>
.
Now, let's modify the app/(tabs)/index.tsx:
- Import the
<EmojiPicker>
component. - Create an
isModalVisible
state variable with theuseState
hook. Its default value isfalse
, which hides the modal until the user presses the button to open it. - Replace the comment in the
onAddSticker()
function to update theisModalVisible
variable totrue
when the user presses the button. This will open the emoji picker. - Create the
onModalClose()
function to update theisModalVisible
state variable. - Place the
<EmojiPicker>
component at the bottom of theIndex
component.
!!!IG15!!!
!!!IG6!!!
Here is the result after this step:
4
Display a list of emoji
Let's add a horizontal list of emoji in the modal's content. We'll use the <FlatList>
component from React Native for it.
Create a EmojiList.tsx file inside the components directory and add the following code:
!!!IG16!!!
!!!IG7!!!
Let's learn what the above code does:
- The
<FlatList>
component above renders all the emoji images using theImage
component, wrapped by a<Pressable>
. Later, we will improve it so that the user can tap an emoji on the screen to make it appear as a sticker on the image. - It also takes an array of items provided by the
emoji
array variable as the value of thedata
prop. TherenderItem
prop takes the item from thedata
and returns the item in the list. Finally, we addedImage
and the<Pressable>
components to display this item. - The
horizontal
prop renders the list horizontally instead of vertically. TheshowsHorizontalScrollIndicator
uses React Native'sPlatform
module to check the value and display the horizontal scroll bar on web.
Now, update the app/(tabs)/index.tsx to import the <EmojiList>
component and replace the comments inside the <EmojiPicker>
component with the following code snippet:
!!!IG17!!!
!!!IG8!!!
In the EmojiList
component, the onSelect
prop selects the emoji and after selecting it, the onCloseModal
closes the modal.
Let's take a look at our app on Android, iOS and the web:
5
Display the selected emoji
Now, we'll put the emoji sticker on the image. Create a new file in the components directory and call it EmojiSticker.tsx. Then, add the following code:
!!!IG9!!!
This component receives two props:
imageSize
: a value defined inside theIndex
component. We will use this value in the next chapter to scale the image's size when tapped.stickerSource
: the source of the selected emoji image.
Import this component in the app/(tabs)/index.tsx file and update the Index
component to display the emoji sticker on the image. We'll check if the pickedEmoji
state is not undefined
:
!!!IG18!!!
!!!IG10!!!
Let's take a look at our app on Android, iOS and the web:
Summary
Chapter 5: Create a modal
We've successfully created the emoji picker modal and implemented the logic to select an emoji and display it over the image.
In the next chapter, let's add user interactions with gestures to drag the emoji and scale the size by tapping it.