React-Native开发鸿蒙NEXT-从global变量聊聊代码的内部优化
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.5; margin-top: 35px; margin-bottom: 10px; padding-bottom: 5px }
.markdown-body h1 { font-size: 24px; line-height: 38px; margin-bottom: 5px }
.markdown-body h2 { font-size: 22px; line-height: 34px; padding-bottom: 12px; border-bottom: 1px solid rgba(236, 236, 236, 1) }
.markdown-body h3 { font-size: 20px; line-height: 28px }
.markdown-body h4 { font-size: 18px; line-height: 26px }
.markdown-body h5 { font-size: 17px; line-height: 24px }
.markdown-body h6 { font-size: 16px; line-height: 24px }
.markdown-body p { line-height: inherit; margin-top: 22px; margin-bottom: 22px }
.markdown-body img { max-width: 100% }
.markdown-body hr { border-top: 1px solid rgba(221, 221, 221, 1); border-right: none; border-bottom: none; border-left: none; margin-top: 32px; margin-bottom: 32px }
.markdown-body code { border-radius: 2px; overflow-x: auto; background-color: rgba(255, 245, 245, 1); color: rgba(255, 80, 44, 1); font-size: 0.87em; padding: 0.065em 0.4em }
.markdown-body code, .markdown-body pre { font-family: Menlo, Monaco, Consolas, Courier New, monospace }
.markdown-body pre { overflow: auto; position: relative; line-height: 1.75 }
.markdown-body pre>code { font-size: 12px; padding: 15px 12px; margin: 0; word-break: normal; display: block; overflow-x: auto; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.markdown-body a { text-decoration: none; color: rgba(2, 105, 200, 1); border-bottom: 1px solid rgba(209, 233, 255, 1) }
.markdown-body a:active, .markdown-body a:hover { color: rgba(39, 91, 140, 1) }
.markdown-body table { display: inline-block !important; font-size: 12px; width: auto; max-width: 100%; overflow: auto; border: 1px solid rgba(246, 246, 246, 1) }
.markdown-body thead { background: rgba(246, 246, 246, 1); color: rgba(0, 0, 0, 1); text-align: left }
.markdown-body tr:nth-child(2n) { background-color: rgba(252, 252, 252, 1) }
.markdown-body td, .markdown-body th { padding: 12px 7px; line-height: 24px }
.markdown-body td { min-width: 120px }
.markdown-body blockquote { color: rgba(102, 102, 102, 1); padding: 1px 23px; margin: 22px 0; border-left: 4px solid rgba(203, 203, 203, 1); background-color: rgba(248, 248, 248, 1) }
.markdown-body blockquote:after { display: block; content: "" }
.markdown-body blockquote>p { margin: 10px 0 }
.markdown-body ol, .markdown-body ul { padding-left: 28px }
.markdown-body ol li, .markdown-body ul li { margin-bottom: 0; list-style: inherit }
.markdown-body ol li .task-list-item, .markdown-body ul li .task-list-item { list-style: none }
.markdown-body ol li .task-list-item ol, .markdown-body ol li .task-list-item ul, .markdown-body ul li .task-list-item ol, .markdown-body ul li .task-list-item ul { margin-top: 0 }
.markdown-body ol ol, .markdown-body ol ul, .markdown-body ul ol, .markdown-body ul ul { margin-top: 3px }
.markdown-body ol li { padding-left: 6px }
.markdown-body .contains-task-list { padding-left: 0 }
.markdown-body .task-list-item { list-style: none }
@media (max-width: 720px) { .markdown-body h1 { font-size: 24px } .markdown-body h2 { font-size: 20px } .markdown-body h3 { font-size: 18px } }.hljs-comment, .hljs-quote { color: rgba(182, 177, 139, 1) }
.hljs-deletion, .hljs-name, .hljs-regexp, .hljs-selector-class, .hljs-selector-id, .hljs-tag, .hljs-template-variable, .hljs-variable { color: rgba(235, 60, 84, 1) }
.hljs-built_in, .hljs-builtin-name, .hljs-link, .hljs-literal, .hljs-meta, .hljs-number, .hljs-params, .hljs-type { color: rgba(231, 206, 86, 1) }
.hljs-attribute { color: rgba(238, 124, 43, 1) }
.hljs-addition, .hljs-bullet, .hljs-string, .hljs-symbol { color: rgba(79, 180, 215, 1) }
.hljs-section, .hljs-title { color: rgba(120, 187, 101, 1) }
.hljs-keyword, .hljs-selector-tag { color: rgba(180, 94, 164, 1) }
.markdown-body pre, .markdown-body pre>code.hljs { background: rgba(28, 29, 33, 1); color: rgba(192, 197, 206, 1) }
.hljs-emphasis { font-style: italic }
.hljs-strong { font-weight: 700 }
React-Native开发鸿蒙NEXT-从global变量聊聊代码的内部优化
原创 悬空八只脚 悬空八只脚 2024年11月07日 21:22 江苏
又到了瞎编点技术帖的时候,很难。题目是上周立的,正文是现在开始写的。早上十点,今天起晚了刚买菜回来,把排骨放水池里泡着,坐下来开始瞎编。
现在是晚上9点,继续来编吧,争取明天能发布。global变量是RN中实现全局变量的一种方式。利用global.xxx可以方便地完成全局传递诸如接口请求配置、临时缓存数据等操作。凡事有利也有弊,global变量的肆意滥用对项目会造成不可想象的协作问题。这些天在将社区RN调整适配HarmonyOS Next,说是适配其实是在重构,自然哪哪感觉有问题都会走走看看。随便搜了下项目中global的使用。
屎山不是一天堆成的。多年的项目,历经多任开发维护后,积攒的量是相当惊人的。更惊人的是:在项目维护的过程中,负责故障修复的小伙伴并不会关注看前任们留下的编码习惯,一番敲敲打打继续上路,无形中又将这种原有的滥用问题进一步扩大。以至于后续开始陆续出现诸如if(global.id || global.Id || global.targetId || global.target_id)之类的无奈判断。
剪不断,理还乱。想要出人头地?先问问绩效答不答应。
以下是一些基于过去项目经验之上的这类问题的优化建议。
优先隔离问题,无论隔离的方法是否是最优解。
优先区分敌我,把问题隔离,不要让问题进一步扩大恶化。冰冻三尺,非一日之寒,代码中的顽疾绝非简单的什么个人习惯问题。面对错综复杂的局势,优先找出一种有效的隔离方法,将问题或替代,或包裹,不追求最优,只为快刀斩乱麻。以项目中的global变量为例,大量且滥用的global变量,根据对项目掌握的经验,大致区分成三大类:1.RN启动时传入的初始化参数 2.初始参数中的一份配置信息,这部分因为用的地方较多可能需要单独抽出 3.在运行中少数需要全局临时缓存的数据。针对现状,简单封装几个方法。大致的逻辑是config和initParam只读,运行中设置的custom可读可写
function configExist() {
return !!global && !!global.config;
}
function configKeyExist(key: string) {
if (configExist()) {
return (key in global.config);
}
return false;
}
function initParamExist() {
return !!global && !!global.initParam;
}
function initParamKeyExist(key: string) {
if (initParamExist()) {
// xLog(' nitParamExist() key = ' + key);
// xLog(' global.initParam = ' + JSON.stringify(global.initParam));
return (key in global.initParam);
}
return false;
}
function customExist() {
return !!global && !!global.custom;
}
function customKeyExist(key: string) {
if (customExist()) {
return (key in global.custom);
}
return false;
}
function getConfig() {
if (configExist()) {
return global.config;
}
return null;
}
function getConfigByKey(key: string) {
if (configKeyExist(key)) {
return global.config[key];
}
return null;
}
function getInitParam() {
if (initParamExist()) {
return global.initParam;
}
return null;
}
function getInitParamByKey(key: string) {
if (initParamKeyExist(key)) {
return global.initParam[key];
}
return null;
}
function clearInitParam() {
if (initParamExist()) {
global.initParam = {};
}
}
function setCustom(key: string, value: any) {
if (!global.custom) {
global.custom = {};
}
global.custom[key] = value;
}
function getCustom() {
if (customExist()) {
return global.custom;
}
return null;
}
function getCustomByKey(key: string) {
if (customKeyExist(key)) {
return global.custom[key];
}
return null;
}
const xnUtils = {
。。。。。。
configExist: configExist,
configKeyExist: configExist,
getConfig: getConfig,
getConfigByKey: getConfigByKey,
initParamExist: initParamExist,
initParamKeyExist: initParamKeyExist,
getInitParam: getInitParam,
getInitParamByKey: getInitParamByKey,
clearInitParam: clearInitParam,
customExist: customExist,
customKeyExist: customKeyExist,
getCustom: getCustom,
getCustomByKey: getCustomByKey,
setCustom: setCustom,
};
export default xnUtils;
完全是粗暴的屏蔽直接使用global,没有彻底解决问题,但将现有代码简单分为"已处理"和"未处理"两部分,在不影响现有业务的情况下进行逐步替代。后续再针对新加入的方法进一步考虑。
万事开头难,走出第一步是最重要的。
根据实际进行评估,确定实际工作量与难度。
评估工作量和工作难度是工作中重要的一环。如何有效评估?建议选择一个现有的功能模块,或者即将开发的新功能,以"彻底替代"为基准进行实际操作,一次评估。这里着重强调的是"彻底"。项目中一个功能模块往往能牵扯出一堆公共类,帮助类这些基础功能结构,在评估的时候按照是否功能模块使用为基准来针对应做替代。往往这部分公共类里包含的工作量在评估的时候是最容易被忽视的,这是容易造成评估时间不足的最大原因。越是古老的项目,积累起来的这种公共类越是盘根错节。
HomeTab.tsx(tab标签-首页)
......
//处理外界直接指定跳转
const goToPage = () => {
xLog(TAG + ' 进入goToPage!');
// absolutePage 表示这是一个绝对页面跳转而不是之前的跳转到详情,absolutePage定义了跳转页面的名字
if (xnUtils.initParamKeyExist('absolutePage')) {
xLog(TAG + ' [goToPage] ' + ' absolutePage = ' + xnUtils.getInitParamByKey('absolutePage'));
// 跳转
navigation.push(xnUtils.getInitParamByKey('absolutePage'), xnUtils.getInitParam());
xnUtils.clearInitParam();
return;
}
......
HomeRecommend.tsx(tab标签-首页中显示推荐内容的部分)
......
/**
* 获取社区广告列表
*/
const getForumAdDataList = () => {
let params = {
sourceFrom: 'APP',
tenantId: xnUtils.getCustomByKey('tenantId'),
forumId: xnUtils.getConfigByKey('forumId'),
searchType: 'HAS_PUBLISH',
// cityCode: this.props.cityCode,
isActive: true,
};
......
NavHeader.tsx(推荐类表中用于显示帖子头像的小组件)
AppService.getPassportByUnionTenant(params)
.then(data => {
setLoading(false);
if (data.errFlag) {
xnToast(data.errMsg);
return;
}
xnUtils.setCustom('tenantId', data.passport.tenantId);
没有调查,就没有发言权。
过程中经常回顾,是否有新的理解。
凡事皆有代价。先下手为强的代价就是对于处理方式需要经常复盘。
抛弃global,改用rudex之类来处理是否是一种更好的选择?
如何在开发过程中去约束这种随意起变量的行为?
开发个插件来辅助处理这些全局变量?
只要在路上,总有到达的一天。
形成文档输出。
如果文档只是用来衡量工作量,那大可不必这么事必躬亲。外行看热闹,内行看门道,把文档看做是对下一任交代的方式。自己经手时间较长的项目一般都会留个readme,或者todo,一句话交代一件事,如"某某时间针对某某问题做了某某调整,具体见wiki某某某"。如果一件事情值得去做,那就值得将这件事情记录下来,告诉后来者曾经走过的路。
我不是在教你做事,我只是在教你如何早点下班。
瞎扯了这么多,看似在聊怎么去优化满屏飞的global变量,实际是在交流如何去优化类似这种代码内部的顽疾。内部的优化往往不显山露水,属于只可在程序猿之间意会的内容。最后,再聊两点:
优化的时机
新功能迭代的开始或者旧功能的改造是相对较为恰当的时间点。一段比较稳定的开发时间是修改这些顽疾必不可少的条件之一。反之处理故障不是一个顺手修改的好时机选择。而一个暂时没有新迭代产生的项目,你也很难说服上级给你时间去进行这种内部的优化。
顺势而为,不要给自己徒增烦恼。
优化的人
优化前,有必要判断一下:自己是否真的是那个天命之人。
刚接手项目,贸然出手 ,容易翻车。刚加入公司,改故障做业务无疑更能站稳脚跟。对于经手项目较长时间,能在组里说得上话的你来说,干这些内部的优化无可厚非,自然老板或者上级也信任你,愿意给你时间。
还是那句话:
又水了一篇,完成这周预定的1/3,明天就是周末了。看来还得赶一赶。致敬每一位尚在屎山中挣扎的小伙伴。
更多内容可关注
我的公众号悬空八只脚
React-Native开发鸿蒙NEXT-从global变量聊聊代码的内部优化的更多相关文章
- React Native开发 - 搭建React Native开发环境
移动开发以前一般都是原生的语言来开发,Android开发是用Java语言,IOS的开发是Object-C或者Swift.那么对于开发一个App,至少需要两套代码.两个团队.对于公司来说,成本还是有的. ...
- React Native 开发笔记
ReactNativeDemo 学习ReactNative开发,搭建ReactNative第一个项目 React Native 开发笔记 1.安装Homebrew $ /usr/bin/ruby -e ...
- React Native开发中自动打包脚本
React Native开发中自动打包脚本 在日常的RN开发中,我们避免不了需要将我们编写的代码编译成安装包,然后生成二维码,供需要测试的人员扫描下载.但是对于非原生的开发人员来说,可能不知如何使用X ...
- 【RN - 基础】之Windows下搭建React Native开发环境
前言 React Native由Facebook公司于2015年F8大会上开源,其主张“Learn once, write everywhere”.React Native的核心设计理念是:既拥有Na ...
- React Native开发入门
目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料 一.前言 虽然只是简单的了解了一下Reac ...
- React Native开发技术周报2
(1).资讯 1.React Native 0.22_rc版本发布 添加了热自动重载功能 (2).技术文章 1.用 React Native 设计的第一个 iOS 应用 我们想为用户设计一款移动端的应 ...
- React Native开发技术周报1
(一).资讯 1.React Native 0.21版本发布,最新版本功能特点,修复的Bug可以看一下已翻译 重要:如果升级 Android 项目到这个版本一定要读! 我们简化了 Android 应用 ...
- DECO 一个REACT NAtive 开发IDE工具
DECO 一个REACT NAtive 开发IDE工具. 目前只支持 OS,NO WINDOWS https://www.decosoftware.com/ 一个方便的快速 ERXPRESS 教程:h ...
- React Native 开发之 (02) 用Sublime 3作为React Native的开发IDE
Sublime Text是一个代码编辑器.也是HTML和散文先进的文本编辑器.漂亮的用户界面和非凡的功能,例如:迷你地图,多选择Python插件,代码段等等.完全可自定义键绑定,菜单和工具栏等等.漂亮 ...
- 【转】【React Native开发】
[React Native开发]React Native控件之ListView组件讲解以及最齐全实例(19) [React Native开发]React Native控件之Touchable*系列组 ...
随机推荐
- Elasticsearch搜索引擎学习笔记(三)
索引的一些操作 集群健康 GET /_cluster/health 创建索引 PUT /index_test { "settings": { "index": ...
- git安装教程以及生成git ssh key
问题 GitHub拉取代码需要SSH,总是忘记命令,现网百度.记录下来,以后靠自己的博文 第一步 安装git 地址: https://git-scm.com/download/win 安装它 第二步 ...
- 重生之数据结构与算法----队列&栈
简介 上文说到,数据结构只有两种.其它的数据结构都是它的整花活. 栈 栈只能在表的一端(称为栈顶)进行插入和删除操作,遵循 "后进先出"(Last In First Out,LIF ...
- HTTP请求中包含账号密码
如果你需要在HTTP请求中包含账号密码,你可以使用基本的HTTP身份验证.在C#中,你可以通过设置 HttpClient 的 DefaultRequestHeaders 来添加身份验证信息.以下是修改 ...
- 2个月搞定计算机二级C语言——真题(8)解析
1. 前言 本篇我们讲解2个月搞定计算机二级C语言--真题8 2. 程序填空题 2.1 题目要求 2.2 提供的代码 #include <stdio.h> #define N 3 #def ...
- tsconfig.json报错问题
tsconfig.json报错问题 前言 创建 tsconfig.json 配置文件时,VS Code 会自动检测当前项目当中是否有ts文件,若没有则报错,提示用户需要创建一个ts文件后,再去使用ty ...
- [I.2]个人作业:软件案例分析
项目 内容 这个作业属于哪个课程 2025春季软件工程(罗杰.任健) 这个作业的要求在哪里 [I.2]个人作业:软件案例分析 我在这个课程的目标是 在PSP中精进个人代码技术,在TSP中提高团队合作凝 ...
- GPU的硬件组成及运行原理
GPU的硬件组成 GPU 是一种专门为图形处理而设计的处理器,它的设计目标是在处理大规模.高并发的图形数据时提供高效的计算能力.与 CPU 相比,GPU 的处理器数量更多,每个处理器的计算能力相对较弱 ...
- 基于pandas的数据清洗 -- 异常值的清洗
博客地址:https://www.cnblogs.com/zylyehuo/ 开发环境 anaconda 集成环境:集成好了数据分析和机器学习中所需要的全部环境 安装目录不可以有中文和特殊符号 jup ...
- 全国省市区基础数据SQL插入脚本
整理了一份全国省市区SQL插入脚本,并配上抓取数据读取插入数据库源码,附件下载地址:https://files.cnblogs.com/files/101Love/Region.rar