https://www.gravatar.com/avatar/62e8b71078f520590446ddf0979949dd?s=240&d=mp

分享RN最佳实践

Let's RNers have nothing hard to do

代码规范

讨论背景 相信大家写代码时 对自己都有一些要求,比如下面的 基本期望:写出他人能容易看懂的代码 更高追求:写出他人看起来很爽的代码 每经历一个阶段,大家都对编码有不同程度的进步提升,可以分享;同时也会积累一些场景下代码如屎的烦恼,想要破局。 于是,阶段性的,需要一个机会,大家开个交流会进行讨论 (对于每个个体)互通有无,集思广益,团队每人都有所提升 (对于互相之间协作)更多地了解到彼此 阅读代码、写代码的风格习惯,增进理解 (对于工作)对现阶段遇到的痛点,找出更优解,或制定调研计划 每次讨论,规范条款上的收获,不在于多少,至少会收获了一些代码细节上的技巧或认知,最重要的是 大大增进了互相的了解,协作起来将越来越紧密顺畅。 讨论成果 组件代码结构 关键点: 打开文件后,更方便的看到核心代码(那就尽量靠前咯) 也就是 render/return组件 之前的代码量尽可能少;那么,就需要通过函数提炼、划分职责等方式转移到别处。 组件代码 书写顺序 示例如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 // AAView.

学习《React Hooks 核心原理与实战》笔记

《React Hooks 核心原理与实战》学习 hooks Q: 为什么 Facebook 要发明React Hooks?React Hooks 解决了什么问题? A: 简化了逻辑重用 hooks之前,复用逻辑要用到高阶组件或者render props 组件每次渲染,内部的函数会重新创建,导致 接收传递函数的子组件 也重新渲染 useCallback 对组件间传递的 (回调)函数 尽量都包裹 useMemo 缓存计算 useCallback,useMemo 只是为了避免 React 组件的重复渲染而导致的性能损失。 而对于原生的节点,比如 div, input 这些,它们已经是原子节点了,不再有子节点, 所以不存在重复刷新带来的性能损失。 useEffect执行时机是 DOM渲染后 useEffect中用到的变量,需要作为依赖参数 拆分复杂组件:不同逻辑拆到不同的Hooks里 Context 适用场景:仅 主题色、语言切换 redux 数据共享 避免不必要的请求 state 使用注意 state 避免定义多余的,找唯一数据源头 去发起改变 上次同事libin提到过这个场景:A传参value1给B,B又传value1给C,C里面能触发改变value1 方案1:C中的操作触发value1变更时,C不维护value1 state,由C回调给B再回调给A,由A改变value1,从而重新渲染B、C 方案2:C中的操作触发value1变更时,C改变C内部的value1,同时回调给B、A去更新(C外部)对应的value1 根据这篇来看,更倾向于方案1 。避免在子组件定义多余的state(value1),找唯一数据源头A 去发起改变 设计模式 所谓「设计模式」,就是针对特定场景,提供一种公认的最佳实践 保证状态的唯一数据源 语义化的拆分复杂组件 Hooks 的一个重要规则,即:Hooks 必须在顶层作用域调用 而不能放在条件判断、循环等语句中,同时也不能在可能的 return 语句之后执行。换句话说,Hooks 必须按顺序被执行到。 容器模式,把条件判断的结果放到两个组件之中。可用Hooks替代 1 2 3 4 function CounterRenderProps({ children }) { .

实现 差不多理想的极简RN弹窗

Q: 代码调用一个弹窗的极简方式是怎样的? A: 这样子👉🏻 XxModuleAlert.show({..}) 为了这个极简用法的目标,我曾经 使用rn-global-modal封装过TextInputAlert,但依然有些问题或难用点,比如遮挡了Toast、更改mask颜色要改源码、布局上有些非正常的地方 因为不希望弹窗遮挡Toast,于是研究了react-native-root-toast,用的react-native-root-siblings,从而找到了封装理想弹窗的更快的方式 于是,基于react-native-root-siblings 5.0.1,造了一个 AlertManager Why need AlertManager 相信大家使用过RN官方Modal的,都知道,iOS弹窗无法弹两个,使用起来不满足高内聚低耦合,难受。。。 RN官方Modal 缺点:耦合过多!须visible属性,多1个import useState,多1行代码setVisble声明,弹窗组件须嵌入容器组件 rn-global-modal 优点:函数式调起弹窗,任意处可调用 缺点:iOS 不支持同时多层弹窗;toast的层级低于它 导致看不到/看不清 What AlertManager provide 封装者:封装出高度解耦的弹窗。 使用方:使用极简! 优势 vs Modal:去掉visible vs rn-global-modal: 支持多层弹窗, TextInput弹窗对键盘支持更好?? How to use AlertManager 使用方: 1 2 XxModuleAlert.show({...}); XxModuleAlert.hide(); 封装方: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class XxModuleAlert { static show() { AlertManager.show(<XxModuleView />, { key: XxModuleView.

封装 低耦合、易用的文本输入框弹窗

效果展示/UI 切换输入法,避开键盘 输入/粘帖时,文字换行,输入框高度准确变化 使用/Usage 封装后,如下这样使用,解耦的干干净净 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import TextInputAlert from "./TextInputAlert"; TextInputAlert.show({ text: "hello", // maxLength: 20, onChange: function didInputChange(text_) { console.log("didInputChange::>>", text_); }, onCompleted: () => { console.log("onCompleted::>>", content); }, }); TextInputAlert.hide(); 像原生一样调api方式展示弹窗,不需要Modal那样耦合过多(视图嵌入、visible字段控制…) 源码/Code TextInputAlert

封装常用基础组件

目录 瀑布流列表base组件 图片base组件 状态栏导航栏组件 页面左上角的返回按钮组件 瀑布流列表base组件 源码:BaseList.js 优点:将下拉刷新、上拉加载更多相关的 pageNo逻辑,封装到BaseList中,使用方仅需关注 数据请求的api,让使用方代码量降到最少。 使用示例 平替 FlatList 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import BaseList from "app/components/list/base"; import { getFanList } from "./service"; const pageSize = 10; const FanList = (props) => { const { userId } = props; const _requestFunc = (page, pageSize) => { return getFanList({ userId: userId, pageNo: page, pageSize }); }; const _renderItem = ({ item, index }) => { return <Item {.

模仿抖音、小红书 输入 #标签 高亮

需求 当输入 以#开头的字符串,则判定为标签 并展示为蓝色 效果图 调研 iOS的TextField可以设定attributedString富文本,但RN的TextInput是不具备的。 方案: TextInput上浮一个style大小一致的Text,TextInput文字颜色设为透明,Text内嵌套 style为蓝色的Text 用来展示#任意(至少1个)字符 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 import React, { useState } from "react"; import { View, TextInput, Text, StyleSheet } from "react-native"; const App = () => { const [text, setText] = useState(""); const handleTextChange = (inputText) => { // 检测输入字符串中是否包含 "#" if (inputText.