前言
我的App应用程序上需要一个抽屉菜单。React navigation drawer导航支持此功能,但是改变了屏幕的结构,我不希望更改,因为我只是其中一个屏幕上需要用到这个简单抽屉菜单组件。大致的效果如下:
安装依赖
react-native-modal
组件大致可以满足我的需求,模态框加上左右移入移出的动画加上手势基本能实现侧拉抽屉的组件。现在安装它:
1 | yarn add react-native-modal -save |
编写SideMenu.js
SideMenu组件是侧拉菜单里面展示的内容
1 | import React from 'react'; |
1 | import { StyleSheet } from 'react-native'; |
编写主页面
引用组件,通过isVisible
参数控制菜单显示隐藏,toggleSideMenu
方法控制切换显示隐藏,还有一些控制入场动画的参数。我为了使它更接近抽屉组件,所以使用slideInLeft
。
1 | import React, { useState } from 'react'; |
1 | import { StyleSheet } from 'react-native'; |
封装
因为其他时候有可能部分页面也需要类似的抽屉组件,所以把这个Modal
组件封装一下,首先想到我们需要在外部(有可能是在页面头部菜单)点击出发显示菜单的功能,所以必须暴露给父组件调用子组件内部方法,那么我们就需要forwardRef
和useImperativeHandle
:forwardRef
:引用父组件的ref实例,成为子组件的一个参数,可以引用父组件的ref绑定到子组件自身的节点上.useImperativeHandle
: 第一个参数,接收一个通过forwardRef引用父组件的ref实例,第二个参数一个回调函数,返回一个对象,对象里面存储需要暴露给父组件的属性或方法;
官方建议useImperativeHandle
和forwardRef
同时使用,减少暴露给父组件的属性,避免使用 ref 这样的命令式代码。
正常情况下 ref 是不能挂在到函数组件上的,因为函数组件没有实例,但是 useImperativeHandle
为我们提供了一个类似实例的东西。它帮助我们通过 useImperativeHandle
的第 2 个参数,所返回的对象的内容挂载到 父组件的 ref.current
上。forwardRef
会创建一个React
组件,这个组件能够将其接受的 ref
属性转发到其组件树下的另一个组件中。
封装Drawer
后,如下:
1 | import React, { useState, useImperativeHandle } from 'react'; |
父组件使用:
1 | import React, { useRef, useState } from 'react'; |
- 本文链接:https://cong1223.github.io/2021/05/18/react-native-drawer/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub IssuesGitHub Discussions