Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >React Native | Radio 组件记录

React Native | Radio 组件记录

原创
作者头像
花花Binki
发布于 2024-04-03 16:13:38
发布于 2024-04-03 16:13:38
3630
举报
文章被收录于专栏:岚的工作随笔岚的工作随笔
封面
封面

前言

公司之前一版的手机应用没有做业务、控制分离的处理,导致其他项目参考时,很难复用其中的功能。所以leader决定近期目标是封装一套公司内部用的基础组件和业务组件,目标是快速,试水。本篇记录一个花费时间较长的组件Radio。

使用技术

  • React & React Native
  • useState,useContext,useRef
  • TypeScript
  • Function Component

设计&实现

作为一个主Java后端开发的人来说,设计一个前端的组件往往是参照常见的App。这次的比较简单,只需要找两个图标,见下图:

select 图标
select 图标

为了符合当前主题,改成蓝色即可。

结构

src ├─assets // 资源 │ └─img // 图片 │ radio_button_select.png // 选中 │ radio_button_unselect.png // 非选中 ├─components //组件位置 │ └─radio │ PropsType.tsx // 组件属性 & 接口 │ Radio.tsx // 单个选项 │ RadioContext.tsx // 上下文 │ RadioGroup.tsx // 组

组件属性 & 接口

代码语言:typescript
AI代码解释
复制
// Radio的接口
export interface IRadio {
  /** 值 */
  value: string;
  /** 显示的文本 */
  label: string;
  /** 默认被选中 */
  defalutChecked?: boolean;
  /** 改变事件 */
  onChange?: (value: boolean) => void;
}

前面三个都可以理解,最后一个是想到下面一种场景:

调查问卷中,根据不同选项,会有后续不同的问题。此时用来触发其他联动事件。

Radio

设计草图
设计草图

根据草图,想象得到是图片 + 文本的结构。再用可点击的控件包裹,于是得到如下

代码语言:jsx
AI代码解释
复制
    <Pressable
      onPress={() => {
        const changedValue = !checked;
        setChecked(() => changedValue);
        context?.onChange(value);
      }}>
      <View style={styles.container}>
        <Image
          style={styles.img}
          source={checked ? selectImgPath : unSelectImgPath}
        />
        <Text style={styles.text}>{label}</Text>
      </View>
    </Pressable>

补充说明:

  • Pressable: 初版使用的是TouchableHighlight,但官方文档中说,未来以Pressable为中心,所以就没再用。该控件是为了模拟点击时候的高亮,并且支持了更细颗粒度的触控效果,见下图:
官方文档摘选
官方文档摘选
  • 第四行的 setChecked(() => changedValue);

需要在内部定义:

代码语言:jsx
AI代码解释
复制
const [checked, setChecked] = useState(false);

是用来让画面上的显示和内部属性双向绑定,useState内部的值为初始值,可以是很多类型,甚至函数。

使用格式也比较固定,假设xxx为属性名,是布尔(boolean)类型,那么得到如下:注意大小写

代码语言:jsx
AI代码解释
复制
const [xxx, setXxx] = useState(false)

想要修改值的话,就用第setXxx

Q: 这里的值为什么用箭头函数() => {}再包裹一下? A: 有时候需要调用完set方法后,直接拿到修改后的值再去做其他修改。 比如你点击之后,想log一下看看真实的值,会发现一直保留上次的结果,与实际不同步。 这时候需要考虑使用这种方式了。主要问题来自React的渲染机制。

  • 第5行保留,后面说
  • style={styles.xxx} 没有配置统一的主题,都写在各自的控件中。
代码语言:jsx
AI代码解释
复制
// 引入的控件
import {Image, Pressable, StyleSheet, Text, View} from 'react-native';
。。。省略
// 图片路径
const selectImgPath = require('../../assets/img/radio_button_select.png');
const unSelectImgPath = require('../../assets/img/radio_button_unselect.png');
。。。省略
const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },
  img: {
    height: 20,
    width: 20,
  },
  text: {
    fontSize: 16,
    marginLeft: 10,
  },
});

RadioGroup 和 RadioGroupContext

用普通的View包裹即可,再加上一些样式。

甚至定义都可以写成:

代码语言:jsx
AI代码解释
复制
// ViewProps来自原生组件View的接口
const RadioGroup = (props: ViewProps) => {...

到这里,画面就结束了。

但其实控件是“死”的,目前还没有控制住“单选”这一功能,而且外面(父组件)也拿不到我选了什么。

这时候一个Hooks的作用就出现了!那就是useContext

代码语言:jsx
AI代码解释
复制
import * as React from 'react';

// 接口定义
interface IRadioGroupContext {
  /** 当前选中的值 */
  currentValue: string;
  /** 更改事件 */
  onChange: (value: string) => void;
}
// 创建上下文
const RadioGroupContext = React.createContext<IRadioGroupContext | null>(
  null,
);
// 导出&起别名
export const RadioGroupContextProvider = THSRadioGroupContext.Provider;
// 导出
export default RadioGroupContext;

RadioGroup中的使用:

代码语言:jsx
AI代码解释
复制
  const onChange = (targetValue: string) => {
    setCurrentValue(() => targetValue);
  };

  return (
    <View style={styles.container}>
      <RadioGroupContextProvider
        value={{
          currentValue: currentValue,
          onChange: onChange,
        }}>
        {children}
      </RadioGroupContextProvider>
    </View>
  );

将需要使用上下文的组件包裹起来,然后所有的值放在value中,这样就成了全局共享的变量、方法。

Radio中的第5行就是为了调用父组件的方法。另外补充:

代码语言:jsx
AI代码解释
复制
  // 得到上下文
  const context = useContext(RadioGroupContext);

  useEffect(() => {
    setChecked(() => context?.currentValue === value);
  }, [context?.currentValue, value]);

useEffect是组件初始化和再次渲染都会执行的方法,第二个参数是调用了外部的变量就会触发更新。

效果图

效果图
效果图

让外面取到当前的值

使用的是useRef,主要分两步骤

  • 第一:包裹原组件
代码语言:jsx
AI代码解释
复制
const RadioGroup = forwardRef((props: IRadioGroup, ref: RefRadio) => {...});
  • 第二:暴漏属性、方法
代码语言:jsx
AI代码解释
复制
  useImperativeHandle(ref, () => {
    currentValue;
  });

外面要想取得,就可以这样

代码语言:jsx
AI代码解释
复制
const radioRef = React.useRef<any>(null);
。。。
console.log(ref.?current?.currentValue)
。。。
 <RadioGroup ref={radioRef}>。。。

使用文档

正确来说,要引入StoryBook库来展示。可是时间,能力有限,就采用Excle的方式了。

格式是组件名,图例,使用,接口属性。

总结

以上就是一个简单的Radio组件开发流程了。

作为一个后端同学,对于React的开发还是比较好上手的,只是有些时候会比较难理解一些函数钩子(Hooks)。比如踩过无数次坑的useMemo,以至于现在都不怎么考虑使用了。

还有一点需要注意的就是做好规范,搭建项目的时候,把eslint的配置统一。包括eslint react的插件,能帮助我们更安全高效的使用和学习React Native。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
天天用 antd 的 Form 组件?自己手写一个吧
用 Form.Item 包裹 Input、Checkbox 等表单项,可以定义 rules,也就是每个表单项的校验规则。
神说要有光zxg
2024/04/10
4630
天天用 antd 的 Form 组件?自己手写一个吧
React Native学习笔记(三)—— 样式、布局与核心组件
React Native 有一个内置的命令行界面,你可以用它来生成一个新项目。您可以使用 Node.js 附带的 访问它,而无需全局安装任何内容。让我们创建一个名为“AwesomeProject”的新 React Native 项目:npx
张果
2023/04/12
15.3K0
React Native学习笔记(三)—— 样式、布局与核心组件
React 单选按钮 Radio Button 详解
单选按钮(Radio Button)是 Web 开发中常用的表单控件之一,用于在多个选项中选择一个。在 React 中,使用单选按钮可以非常方便地管理状态和用户交互。本文将从基础概念出发,逐步深入探讨 React 中单选按钮的常见问题、易错点及如何避免,并通过代码案例进行详细解释。
Jimaks
2024/12/12
6870
React 单选按钮 Radio Button 详解
React Native之常用第三方库
前言 React Native出来一年多了,受到各大开发人员的喜爱,但是由于只是专注于View层的开发,因此在很多深层次上还需要结合原生app做一定的兼容,还有就是现在好多控件,如Android中已是系统的控件的sidemenu、checkbox、gridview等,这些在react native中 系统是没有给我们提供的,这时候就借助了第三方开源的力量。 那么我们今天说说在React Native项目开发中常见的一些第三方库。 常见的第三方库 组件篇 CheckBox(多选按钮) react-nati
xiangzhihong
2018/02/05
9.4K0
React Native之常用第三方库
React 实现一个markdown[2]
theme: channing-cyan highlight: a11y-light
用户4793865
2023/02/03
1.3K0
一篇看懂 React Hooks
React Hooks 是 React 16.7.0-alpha 版本推出的新特性,想尝试的同学安装此版本即可。
前端迷
2019/08/05
3.9K0
入门 TypeScript 编写 React
Create React App 是一个官方支持的创建 React 单页应用程序的CLI,它提供了一个零配置的现代构建设置。当你使用 Create React App 来创建一个新的 TypeScript React 工程时,你可以运行:
icepy
2019/06/24
5.5K0
React Native组件只Image
不管在Android还是在ios原生的开发中,图片都是作为控件给出来的,在RN中也有这么一个控件(Image)。根据官网的资料,图片分为本地静态图片,网络图片和混合app资源。一下分类介绍来源官网。 静态图片资源 从0.14版本开始,React Native提供了一个统一的方式来管理iOS和Android应用中的图片。要往App中添加一个静态图片,只需把图片文件放在代码文件夹中某处,然后像下面这样去引用它: <Image source={require('./my-icon.png')} /> 图片文件
xiangzhihong
2018/02/05
2K0
React Native组件只Image
React Native之ViewPagerAndroid 组件
概述 今天我们来讲解一下关于 ViewPager 的使用,它是一个允许子视图左右滚动翻页的容器。我们知道在Android开发中系统有ViewPager这个组件,作用是实现滚动翻页的,在RN中也是有这么一个组件的(ViewPagerAndroid),每一个ViewPagerAndroid的子容器会被视作一个单独的页,并且会被拉伸填满ViewPagerAndroid。 我们来看一段官方给出的例子: render: function() { return ( <ViewPagerAndroid
xiangzhihong
2018/02/05
1.1K0
React Native之ViewPagerAndroid 组件
React-Native组件之 Navigator和NavigatorIOS
对于app而言,一款应用往往涉及到很多的页面,而页面之间的跳转Android和iOS实现也各不相同。在iOS上,系统为我们提供了UINavigationController控件用来专门控制页面的跳转,iOS的实现思路很清晰,为按钮添加action事件,点击之后跳转到指定的页面即可。例如: //定义一个Button,点击后跳转到另一个页面 UIButton * button=[UIButton buttonWithType:UIButtonTypeSystem]; button.frame=C
xiangzhihong
2018/02/06
5.1K0
React-Native组件之 Navigator和NavigatorIOS
React Native 系列(五) -- 组件间传值
前言 本系列是基于React Native版本号0.44.3写的。任何一款 App 都有界面之间数据传递的这个步骤的,那么在RN中,组件间是怎么传值的呢?这篇文章将介绍到顺传、逆传已经通过通知传值。
Scott_Mr
2018/05/16
1.7K0
精读《怎么用 React Hooks 造轮子》
上周的 精读《React Hooks》 已经实现了对 React Hooks 的基本认知,也许你也看了 React Hooks 基本实现剖析(就是数组),但理解实现原理就可以用好了吗?学的是知识,而用的是技能,看别人的用法就像刷抖音一样(哇,饭还可以这样吃?),你总会有新的收获。
黄子毅
2022/03/14
2.6K0
react-native导航组件
创建 src/navigation.js 文件,在其中添加一个导航器组件,以及两个屏幕组件 HomeScreen 和 ProfileScreen。同时在这两个屏幕组件中添加一个按钮,用于导航到另一个屏幕组件。
kongxx
2024/06/17
3580
精读《React — 5 Things That Might Surprise You》
状态管理是 React 的基础,虽然useState可能是最常见的钩子,但可能对其实际行为有些不了解。让我们来看看以下组件:
落落落洛克
2021/09/17
1.3K0
精读《React — 5 Things That Might Surprise You》
React Native控件只TextInput
TextInput是一个允许用户在应用中通过键盘输入文本的基本组件。本组件的属性提供了多种特性的配置,譬如自动完成、自动大小写、占位文字,以及多种不同的键盘类型(如纯数字键盘)等等。 比如官网最简单的写法: import React, { Component } from 'react'; import { AppRegistry, TextInput } from 'react-native'; class UselessTextInput extends Component { construct
xiangzhihong
2018/02/05
4K0
React Native控件只TextInput
React Native 集成 ArcGIS 地图
ArcGIS官方提供了 JavaScript SDK,也提供了 ArcGIS-Runtime-SDK-iOS,但是并没有提供 React Native的版本,所以这里使用了 react-native-arcgis-mapview 库,这个库比较老,支持的 ArcGIS-Runtime-SDK-iOS 版本是100.4,但是在使用的时候发现,在使用pod install安装的时候总是会下载失败,所以后面手动将 ArcGIS-Runtime-SDK-iOS 的版本改为 100.14.1。
kongxx
2024/06/21
2180
react-native学习之入门app
1、项目初始化: react-native init MyProject 2、启动项目: cd MyProject react-native start 新开cmd窗口: react-native r
用户1141560
2017/12/26
1.2K0
在爱 context 一次,并结合 useReducer 使用,这次有一点简单
在 React 中,props 能够帮助我们将数据层层往下传递。而 context 能够帮助我们将数据跨层级往下传递。
用户6901603
2023/12/20
3270
在爱 context 一次,并结合 useReducer 使用,这次有一点简单
react-native布局与组件
一款好的App离不开漂亮的布局,RN中的布局方式采⽤的是FlexBox(弹性布局) 。
一粒小麦
2019/09/17
6K0
react-native布局与组件
React Native 系列(八) -- 导航
前言 本系列是基于React Native版本号0.44.3写的。我们都知道,一个App不可能只有一个不变的界面,而是通过多个界面间的跳转来呈现不同的内容。那么这篇文章将介绍RN中的导航。 导航 什么是导航? 其本质就是视图之间的界面跳转,例如首页跳转到详情页。 在RN中有两个组件负责实现这样的效果,它们是: NavigatorIOS React Navigation 你可能在很多地方听说过Navigator,这个老组件会逐渐被React Navigation代替。笔者在最后也会讲解一下Navigator
Scott_Mr
2018/05/16
6.8K0
相关推荐
天天用 antd 的 Form 组件?自己手写一个吧
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档