ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

React Native Elements ButtonGroup 实战指南:单选、多选与组件化按钮的完整用法

React Native Elements ButtonGroup 实战指南:单选、多选与组件化按钮的完整用法 React Native Elements ButtonGroup 实战指南单选、多选与组件化按钮的完整用法【免费下载链接】react-native-elementsCross-Platform React Native UI Toolkit项目地址: https://gitcode.com/gh_mirrors/re/react-native-elementsButtonGroup按钮组是 React Native Elements 中用于呈现一组紧密相关、互斥选项的线性分段组件常见于筛选器、切换器、富文本工具条等场景。本指南以官方示例文档snack 示例为主线结合组件源码与测试用例带你掌握字符串按钮、多选模式、组件按钮三种形态以及受控状态、样式定制、禁用与主题化等完整能力。一、ButtonGroup 是什么在动手写代码之前先明确组件的定位。源码注释给出了官方定义见 ButtonGroup.tsxButtonGroup 是一组线性的分段segments每一段都像一个按钮可以显示不同的视图或执行不同的操作。请用它来呈现紧密相关但互斥的选择。典型场景包括切换列表视图网格/列表、富文本编辑器的对齐方式切换、筛选条件的单选/多选等。组件继承 React Native 原生触摸组件如Pressable、TouchableHighlight的全部属性底层交互能力与原生组件一致。本文围绕的官方示例位于 website/versioned_docs/version-4.0.0-beta.0/main/usage/ButtonGroup/snack/index.md示例本身是一个可直接在 Expo Snack 中运行的可交互代码片段被上层文档 ButtonGroup.md 通过Snack /方式嵌入展示。示例从Using Strings字符串按钮与Using Components组件按钮两个维度演示核心用法。二、基础用法字符串按钮与单选模式原文档的第一个示例演示了最基础也最常见的形态——以字符串数组定义按钮配合受控的selectedIndex与onPress实现单选。以下代码即为原示例的完整继承补全了样式定义import React, { useState } from react; import { ButtonGroup } from react-native-elements; import { Text, StyleSheet } from react-native; export default () { const [selectedIndex, setSelectedIndex] useState(0); return ( Text style{styles.subHeader}Using Strings/Text ButtonGroup buttons{[SIMPLE, BUTTON, GROUP]} selectedIndex{selectedIndex} onPress{(value) { setSelectedIndex(value); }} containerStyle{{ marginBottom: 20 }} / / ); }; const styles StyleSheet.create({ subHeader: { backgroundColor: #2089dc, color: white, textAlign: center, paddingVertical: 5, marginBottom: 10, }, });关键点拆解buttons必填属性接收字符串数组组件会为每个字符串渲染一个分段按钮。selectedIndex当前选中项的索引类型为number | null默认null。这是一个受控属性选中状态完全由你传入的值决定。onPress点击回调参数是被点击按钮的索引而非按钮内容。示例中把索引写回useState完成受控更新。containerStyle作用于整个按钮组容器的样式示例用它调整了底部间距。这种受控索引 回调回写的模式是 ButtonGroup 的单选标准写法组件自身不维护选中状态状态始终由业务组件持有因此切换页面、重置筛选时只需重置selectedIndex即可。测试用例印证了这一契约在 ButtonGroup.test.tsx 中fireEvent.press(buttonComponents[1])后断言onPress被以1调用即回调永远携带被点击分段的索引。三、多选模式selectMultiple 与 selectedIndexes原文档第二个示例演示多选通过selectMultiple开启多选能力并用数组selectedIndexes记录所有选中索引。这是Using Strings部分在单选之外的另一核心用法import React, { useState } from react; import { ButtonGroup } from react-native-elements; import { Text, StyleSheet } from react-native; export default () { const [selectedIndexes, setSelectedIndexes] useState([0, 2, 3]); return ( Text style{styles.subHeader}Multiple Select/Text ButtonGroup buttons{[Multiple, Select, Button, Group]} selectMultiple selectedIndexes{selectedIndexes} onPress{(value) { setSelectedIndexes(value); }} containerStyle{{ marginBottom: 20 }} / / ); };多选模式的行为与单选有本质区别从源码 ButtonGroup.tsx 可以看到其内部分发逻辑onPress{() { if (selectMultiple) { if (selectedIndexes.includes(i)) { onPress(selectedIndexes.filter((index) index ! i)); } else { onPress([...selectedIndexes, i]); } } else { onPress(i); } }}单选模式下onPress收到数字索引多选模式下onPress收到新的索引数组点击已选项则从数组中移除取消选中点击未选项则追加选中。示例中初始状态[0, 2, 3]意味着第 0、2、3 项初始即处于选中态。对应测试覆盖在 ButtonGroup.test.tsxselectedIndexes{[0]}时点击索引 2回调收到[0, 2]selectedIndexes{[0, 2]}时再次点击索引 2回调收到[0]验证了增与减两条路径。此外源码中选中态判定为selectedIndex i || selectedIndexes.includes(i)ButtonGroup.tsx因此selectMultiple与selectedIndexes需要配套使用二者缺一不可。四、组件按钮Using Components原文档在Using Strings之后预留了Using Components小节对应源码文件中的注释!-- Example of ButtonGroup with React Component as prop input which is not into snack yet --说明组件形态当时尚未纳入 snack 示例其完整能力可从组件的用法示例与源码中还原。组件按钮有两种写法在官方用法示例 ButtonGroup.usage.tsx 中均有体现写法一直接传 React 元素如 Iconimport React from react; import { ButtonGroup, Icon } from ..; export default () { const [selectedIndex, setSelectedIndex] React.useState(0); return ( ButtonGroup buttonStyle{{ padding: 10 }} selectedButtonStyle{{ backgroundColor: #e2e2e2 }} buttons{[ Icon nameformat-align-left /, Icon nameformat-align-center /, Icon nameformat-align-right /, ]} selectedIndex{selectedIndex} onPress{setSelectedIndex} / ); };这是富文本对齐工具条的经典实现把三个Icon元素作为按钮实现图标型分段切换。写法二传{ element: Component }对象按 ButtonGroup.tsx 的类型定义buttons数组项可以是string | ReactElement | { element: Component }。当传入带element键的对象时组件会通过hasElementKey判定并渲染自定义组件同时注入isSelected属性ButtonGroup.tsxconst buttonObjects [ { element: ({ isSelected }) ( View Text{isSelected ? Selected : Button 1}/Text /View ), }, // ... ]; ButtonGroup buttons{buttonObjects} selectedIndex{0} /;对应测试见 ButtonGroup.test.tsx它同时覆盖了元素与对象两种形态的快照渲染。五、源码视角内部实现与关键 Props5.1 渲染结构与选中样式从 ButtonGroup.tsx 的实现看组件由三层结构组成外层ViewtestIDRNE__ButtonGroupContainer承载容器样式中间层按按钮索引包裹的View负责内部分隔线innerBorderStyle内层可交互组件默认PressabletestIDRNE__ButtonGroupItem及其内容区。选中项默认以主题色theme.colors.primary作为背景、文字变为白色ButtonGroup.tsx按钮文字默认字号为normalizeText(13)、颜色theme.colors.grey2非 Android 平台额外加fontWeight: 500ButtonGroup.tsx。5.2 核心 Props 速查表以下为组件公开的核心 Props源自 ButtonGroup.tsx 的接口定义Prop类型默认值说明buttons(string \| ReactElement \| {element})[]必填按钮内容数组支持字符串、React 元素或{element}对象selectedIndexnumber \| nullnull单选模式当前选中索引selectedIndexesnumber[][]多选模式已选中索引集合selectMultiplebooleanfalse是否开启多选onPress(...args) void() null点击回调单选传索引、多选传新索引数组disabledboolean \| number[]falsetrue禁用全部数组可只禁用指定索引verticalbooleanfalse是否纵向排列containerStyleStylePropViewStyle—最外层容器样式buttonStyleStylePropViewStyle—每个按钮内容区样式buttonContainerStyleStylePropViewStyle—每个按钮外层包裹样式textStyleStylePropTextStyle—按钮文字样式selectedButtonStyleStylePropViewStyle—选中项按钮样式selectedTextStyleStylePropTextStyle—选中项文字样式innerBorderStyle{ color?, width? }{ width: 1, color: theme.colors.grey4 }内部按钮之间的分隔线underlayColorstringtheme.colors.primary按压高亮色activeOpacitynumber—按压透明度disabledStyle/disabledTextStyleStyleProp...—禁用态样式disabledSelectedStyle/disabledSelectedTextStyleStyleProp...—禁用且选中态样式Component组件类型Pressable可替换底层交互组件5.3 内部逻辑要点分隔线规则横向布局时除最后一个按钮外其余按钮右侧绘制borderRight纵向布局时改为底部borderBottomButtonGroup.tsx。默认分隔线宽度为 1、颜色为theme.colors.grey4可通过innerBorderStyle覆盖测试中传innerBorderStyle{{ width: 0 }}可得到无分隔线的效果ButtonGroup.test.tsx。Android 水波纹按压反馈通过androidRipple(Color(underlayColor).alpha(activeOpacity)...)生成ButtonGroup.tsxunderlayColor默认取主题主色。无障碍每个分段按钮都会设置accessibilityState{{ disabled: isDisabled }}ButtonGroup.tsx方便屏幕阅读器感知禁用状态。六、样式定制与布局扩展6.1 横向与纵向布局默认容器样式为横向 flex 布局、圆角 3、高度 40、白底浅灰边框见 ButtonGroup.tsx。传入vertical后布局切换为flexDirection: column每个分段固定高度 40ButtonGroup.tsx适用于侧边筛选菜单等纵向场景。测试对纵向模式断言了flexDirection: column与height: nullButtonGroup.test.tsx。6.2 禁用状态disabled支持两种取值// 禁用全部 ButtonGroup buttons{[A, B, C]} disabled / // 只禁用索引为 1 的按钮 ButtonGroup buttons{[A, B, C]} disabled{[1]} /禁用后的视觉处理由源码内置普通禁用项背景透明、文字通过color(disabled).darken(0.3)变暗被禁用且处于选中态的项背景改为theme.colors.disabledButtonGroup.tsx。四个disabled*系列样式属性可进一步精细定制禁用外观对应测试见 ButtonGroup.test.tsx。七、主题化支持ButtonGroup 是完整的主题化组件。基础实现位于packages/base而面向业务使用的主题化版本位于 packages/themed/src/ButtonGroup/index.tsx它通过withTheme将组件与全局主题上下文绑定export default withThemeButtonGroupProps(ButtonGroup, ButtonGroup);这意味着可以在全局主题中统一配置 ButtonGroup 的默认属性。官方主题测试 packages/themed/src/ButtonGroup/tests/ButtonGroup.test.tsx 演示了用法const testTheme { components: { ButtonGroup: { selectedTextStyle: { color: red, }, }, }, };通过components.ButtonGroup即可为所有 ButtonGroup 实例注入默认selectedTextStyle实现品牌化的统一选中态样式。另外组件内部大量使用theme.colors.primary、theme.colors.grey2、theme.colors.grey4、theme.colors.disabled等主题色ButtonGroup.tsx更换主题色即可全局联动按钮组的默认配色。八、实战要点小结受控组件selectedIndex/selectedIndexes是受控属性务必通过onPress回写状态不要在回调里只console.log而不更新状态。单选与多选回调签名不同单选onPress收到number多选收到number[]处理逻辑需区分。三种按钮内容字符串适合纯文本分段React 元素如Icon适合图标工具条{ element }对象适合需要感知isSelected的自定义组件。容器默认带边距默认marginHorizontal: 10、marginVertical: 5多组并存时注意间距叠加。纵向模式分隔线在底部vertical时innerBorderStyle作用于borderBottom而非borderRight。至此你已经掌握了 React Native Elements 中 ButtonGroup 从基础单选、多选到组件化按钮的完整用法并了解了其源码实现与主题化机制可以据此在项目中灵活构建互斥选择类的交互界面。【免费下载链接】react-native-elementsCross-Platform React Native UI Toolkit项目地址: https://gitcode.com/gh_mirrors/re/react-native-elements创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进