by Dhruvdutt Jadhav
由Dhruvdutt Jadhav
Screen space is a precious commodity on mobile. The drawer menu (or “hamburger menu”) is one of the most popular navigation patterns that helps you save it while offering intuitive navigation. In this post, I will demystify how to build a nested (multi-level) drawer menu using React Native and React Navigation. ?
屏幕空间是移动设备上的宝贵商品。 抽屉菜单 (或“汉堡菜单”)是最受欢迎的导航模式之一,可在提供直观导航的同时帮助您保存它。 在这篇文章中,我将揭开如何使用React Native和React Navigation构建嵌套(多级)抽屉菜单的神秘感。 ?
Try the live demo on mobile?or on web. ?️
Navigation forms the backbone of a huge majority of apps built for production. The look and feel of navigation are important for driving use and engagement in mobile apps.
导航是为生产而构建的绝大多数应用程序的骨干。 导航的外观对于推动移动应用的使用和参与度至关重要。
However, if you are React Native developer, there isn’t a clear opinion when it comes to building a navigation menu. React Native recommends a bunch of libraries for navigation. Each has its strength, depending on your needs, but there’s no one clear winner for all use-cases.
但是,如果您是React Native开发人员,则在构建导航菜单时并没有明确的意见。 React Native 建议使用一堆库进行导航。 每一种都有其优势,取决于您的需求,但是对于所有用例而言,没有一个明显的赢家。
None of the navigation libraries currently support nested drawers out-of-the-box. But one of the libraries that provides a rich API to build custom solutions is React Navigation — a JavaScript-based navigation. It is strongly backed and maintained by the React Native community. This is what we’re going to use in this tutorial.
当前,没有任何导航库支持开箱即用的嵌套抽屉。 但是提供丰富的API来构建自定义解决方案的库之一是React Navigation (基于JavaScript的导航)。 它由React Native社区大力支持和维护。 这就是本教程要使用的内容。
I had to build a playground app to showcase a UI components library for React Native. It consists of eight different components, each supporting various props, and more than 50 different options.
我必须构建一个运动场应用程序来展示React Native的UI组件库。 它由八个不同的组件组成,每个组件都支持各种道具以及50多种不同的选项。
It was not possible to show all options inside the drawer at one time without a multi-level drawer which would scope the options based on the selected component. I couldn’t find a ready-made solution for this, so I needed to build a custom one.
如果没有一个多级抽屉将无法根据所选组件确定选项的范围,则无法一次在抽屉中显示所有选项。 我无法为此找到现成的解决方案,因此我需要构建一个定制的解决方案。
For the base setup, I’m assuming you already have a React Native project setup with either CRNA, Expo Kit, or React Native CLI. Make sure you have the react-navigation library installed with either yarn or npm. We’ll start right off with using the navigation API.
对于基本设置,我假设您已经具有使用CRNA , Expo Kit或React Native CLI的React Native项目设置。 确保您已安装带有yarn或npm的react-navigation库。 我们将从使用导航API开始。
Feel free to check the getting-started guide before proceeding if you aren’t familiar with the React Navigation API.
如果您不熟悉React Navigation API,请在继续之前先阅读入门指南 。
We’ll start with an example similar to the one documented in the React Navigation’s DrawerNavigator official guide. We’ll create a simple drawer that has two drawer items: Home and Notifications.
我们将从一个类似于React Navigation的DrawerNavigator 官方指南中记录的示例开始。 我们将创建一个具有两个抽屉项目的简单抽屉:“主页”和“通知”。
React Navigation enables all navigators to do a lot of customizations by passing a navigator config as the second parameter. We’ll use it to render some custom content other than the stock drawer items.
通过将导航器配置作为第二个参数传递,React Navigation使所有导航器都可以进行很多自定义。 我们将使用它来呈现一些自定义内容,而不是库存项目。
DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)
DrawerNavigator (RouteConfigs, DrawerNavigatorConfig)
We’ll pass a prop called contentComponent
to the config which would allow us to render custom content for the drawer. We’ll use that to show a header and footer along with the prevailing DrawerItems
from react-navigation
.
我们将一个名为contentComponent
的道具contentComponent
给配置,该道具将允许我们为抽屉渲染自定义内容。 我们将用它来显示页眉和页脚以及来自react-navigation
的流行DrawerItems
。
This potentially unlocks a lot of things that can be done by controlling what to render inside the drawer.
通过控制在抽屉内渲染的内容,这有可能解锁很多事情。
We need to build a nested drawer for each component that we want to showcase. So let’s first register all the screens with the DrawerNavigator’s Config. We’ve created a separate screen mapping file for components. You can very well have your own convention, or define the object directly similar to the Home screen component.
我们需要为要展示的每个组件构建一个嵌套的抽屉。 因此,让我们首先使用DrawerNavigator的Config注册所有屏幕。 我们为组件创建了一个单独的屏幕映射文件。 您可以很好地拥有自己的约定,或者直接类似于主屏幕组件定义对象。
The screen mapping consists of simple objects with screen property. The screenMapping
object looks something like this:
屏幕映射由具有屏幕属性的简单对象组成。 screenMapping
对象看起来像这样:
After registering all components, the drawer would look something like this:
注册所有组件后,抽屉将如下所示:
This would render all the components along with their options. We have two main components: DataSearch and TextField. Each has options like “With Icon Position,” “With Placeholder,” and more. Our task is to segregate these into a list of only components (DataSearch, TextField).
这将呈现所有组件及其选项。 我们有两个主要组件: DataSearch和TextField 。 每个选项都有“带有图标位置”,“带有占位符”等选项。 我们的任务是将它们分成仅包含组件(DataSearch,TextField)的列表。
A pattern I followed in the mapping was to use a delimiter _
to group together options from one component. For instance, the navigation keys I used were “DataSearch_Basic” and “DataSearch_With Icon Position”. This is exactly what is going to help us combine the options for a single component like DataSearch. We’ll evaluate uniquely all the components we need to show for the outer drawer.
我在映射中遵循的模式是使用定界符_
将来自一个组件的选项组合在一起。 例如,我使用的导航键是“ DataSearch_Basic”和“ DataSearch_With Icon Position”。 这正是将帮助我们组合单个组件(如DataSearch)的选项的原因。 我们将唯一评估外部抽屉所需显示的所有组件。
We’ll create a util function to evaluate outer drawer list items to render.
我们将创建一个util函数来评估要渲染的外部抽屉列表项。
This function will return an object with unique components for the main components like (DataSearch, TextField) that we’ll render on the screen with the help of the contentComponent
custom component. We’ll also maintain a boolean to determine the content rendered on the drawer at a particular instant.
此函数将返回一个具有唯一组件的对象,这些组件具有主要组件(例如DataSearch,TextField),这些组件将contentComponent
自定义组件在屏幕上呈现。 我们还将维护一个布尔值,以确定在特定时刻渲染在抽屉上的内容。
The renderMainDrawerComponent
is just a function iterating over the keys of the components object. It renders custom outer drawer items built on top of simply Text
and View
from react-native. Check the full code here.
renderMainDrawerComponent
只是一个在components对象的键上进行迭代的函数。 它呈现了基于react-native的简单Text
和View
之上的自定义外部抽屉项目。 在此处检查完整代码。
This will render the drawer like this:
这将使抽屉如下所示:
Now, we need to show the options based on the component that is tapped. You might have noticed that in utils, we’re also extracting the start and end indexes of the component groups based on the delimiter pattern.
现在,我们需要根据所点击的组件显示选项。 您可能已经注意到,在utils中,我们还基于定界符模式提取了组件组的开始索引和结束索引。
For instance, DataSearch screens start at index 1 (index 0 is Home screen) and ends at 3. TextField starts at 3 and end at 5. We’ll use these indices to magically slice the items
that are passed to DrawerItems
based on the selected component and its indices.
例如,DataSearch屏幕从索引1开始(索引0是主屏幕),结束于3。TextField从3开始,结束于5。我们将使用这些索引根据所选内容神奇地切片传递给DrawerItems
的items
组件及其索引。
Now, after tapping on DataSearch, the drawer will yield into something like this:
现在,在点击DataSearch之后,抽屉将产生如下所示的内容:
We’ve also added a sweet back button which basically toggles a boolean to render the main drawer items. You can check the full code here.
我们还添加了一个漂亮的后退按钮,该按钮基本上切换了一个布尔值以呈现主抽屉项目。 您可以在此处查看完整的代码。
Now, the only thing left to do is make the drawer items look cleaner by trimming the redundant component name. Again, the rich React Navigation API comes handy here.
现在,唯一要做的就是通过修剪冗余组件名称来使抽屉项目看起来更整洁。 同样,丰富的React Navigation API在这里很方便。
There are various properties we can pass with navigationOptions
. A particular one we’re going to use here is the title
prop with the screen mapping. This will let us remove the part before the first delimiter. So, “DataSearch_Basic” will show as “Basic” only.
我们可以通过navigationOptions
传递各种属性。 我们将在此处使用的一个特殊title
是带有屏幕映射的title
道具。 这将使我们删除第一个定界符之前的部分。 因此,“ DataSearch_Basic”将仅显示为“ Basic”。
That’s all. We can add as many items we want based on the delimiter pattern. The playground app we’ve built consists of eight main components and over 53 total options.
就这样。 我们可以基于定界符模式添加任意数量的项。 我们构建的游乐场应用程序由八个主要组件组成,共有53个选项。
Base setup: DrawerNavigation hello world from docs.
基本设置 :从DrawerNavigation的hello world 文档 。
Custom drawer content: Render drawer items with contentComponent
.
自定义抽屉内容 :使用contentComponent
渲染抽屉项目。
Group outer drawer: Read delimiter pattern to group drawer items.
Rendering child drawer: Slice and render child drawer items.
渲染儿童抽屉 : 切片并渲染儿童抽屉项目。
We learned to build a multi-level drawer menu with React Native. We used React Navigation API to render a custom content component inside the drawer, and used the delimiter pattern for screen mapping. Use this pattern to build any level of nesting or conditional rendering for drawers.
我们学会了使用React Native构建多级抽屉菜单。 我们使用React Navigation API在抽屉内部渲染自定义内容组件,并使用定界符模式进行屏幕映射。 使用此模式可以为抽屉构建任何级别的嵌套或条件渲染。
Provides UI components for Native and Web platform to build perfect search experiences. You can check all the components it offers by playing with the playground app itself or by creating your own component.
提供用于本机和Web平台的UI组件,以构建完美的搜索体验。 您可以通过使用Playground应用本身或创建自己的组件来检查其提供的所有组件 。
appbaseio/reactivesearchreactivesearch - A React and React Native UI components library for building data-driven appsgithub.com
appbaseio / reactivesearch reactsearch- 一个React和React Native UI组件库,用于构建数据驱动的应用程序 github.com
翻译自: https://www.freecodecamp.org/news/how-to-build-a-nested-drawer-menu-with-react-native-a1c2fdcab6c9/