首页
吐槽
友链
关于
Search
1
【React Native】如何拨打电话?
782 阅读
2
WHMCS官方最新版下载+开心教程
759 阅读
3
为TypeScript项目添加Eslint和Prettier
524 阅读
4
React Native原理和架构
360 阅读
5
本站免费提供微软office A1P、A1账号
306 阅读
前端开发
后端开发
源码分享
技术分享
生活娱乐
影视评价
闲言碎语
登录
Search
标签搜索
ios
前端
JavaScript
阿里
Teambition
typecho
小火箭
shadowsocks
React
React Native
SQL
eslint
prettier
typescript
GraphQL
WHMCS
WHMCS开心版
Zsh
on-my-zsh
代理
夜雨
累计撰写
31
篇文章
累计收到
46
条评论
首页
栏目
前端开发
后端开发
源码分享
技术分享
生活娱乐
影视评价
闲言碎语
页面
吐槽
友链
关于
搜索到
31
篇与
surile
的结果
2021-04-09
React Native 安卓原生角标
使用友盟推送,发现没有集成设置角标功能,因此就自己查阅文档等方式写了一个设置角标的功能。笔者安卓小白,不懂安卓,大神勿喷。React Native 已提供Ios版插件,但对Android并未支持。国内安卓基本上都是深度定制过的,各方产商定制方法各不相同,我选择使用第三方开源的项目实现。环境 "react": "16.9.0", "react-native": "0.61.4",安卓第三方插件ShortcutBadgerShortcutBadger 引入修改android/app/build.gradle... dependencies { implementation "me.leolin:ShortcutBadger:1.1.22@aar" ... } ....实现原生与ReactNative通信新建badge文件夹在badge文件夹中,新建 ShortcutBadgerModule(类)文件 继承 ReacContextBaseJavaModulepackage com.jgadasdapp; 引入自己的包名 import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import me.leolin.shortcutbadger.ShortcutBadger; // 引入外部导入的第三方包 public class ShortcutBadgerModule extends ReactContextBaseJavaModule { static ReactApplicationContext context; public ShortcutBadgerModule(ReactApplicationContext reactContext) { super(reactContext); context = reactContext; } /** * 这个返回的字符串是我们js端调用时会用到的 */ @Override public String getName() { return "ShortcutBadger"; } /** *这个方法是我们js端调用的方法,其中的参数可以从js端传过来 如这里我们js端可以类似 Badge.applyCount(2)来调用这个方法 */ @ReactMethod public void applyCount(int badgeCount){ if(context != null){ ShortcutBadger.applyCount(context,badgeCount); } } @ReactMethod public void removeCount(){ if(context != null){ ShortcutBadger.removeCount(context); } } } 注册模块新建 ShortcutBadgerReactPackage(包)文件 继承 ReactPackagepackage com.jgadasdapp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.shell.MainReactPackage; import com.facebook.react.uimanager.ViewManager; import com.more.shop.badge.ShortcutBadgerModule; /** * Created by surile on 13/5/20. */ public class ShortcutBadgerReactPackage implements ReactPackage { @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } /** * 如需要添加本地方法,只需在这里add * * @param reactContext * @return */ @Override public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new ShortcutBadgerModule(reactContext)); return modules; } }在 MainApplication 里面注册 ShortcutBadgerReactPackage protected List<ReactPackage> getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List<ReactPackage> packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: // packages.add(new MyReactNativePackage()); packages.add(new ShortcutBadgerReactPackage()); return packages; }ReactNative 中调用引入 NativeModulesimport {NativeModules, Platform} from 'react-native'; const ShortcutBadgerModule = NativeModules.ShortcutBadger;设置角标ShortcutBadgerModule.applyCount(1)清除角标ShortcutBadgerModule.removeCount()参考原生模块友盟推送
2021年04月09日
229 阅读
0 评论
1 点赞
2021-04-09
Javascript递归处理数组
前端添加数据,未进入数据库,因此选中的数据,是由name组成,后台将数据返回时,带有id,不能进行删除操作,只能进行修改name操作,因原先是由name组成数据,为了匹配修改的数据,所以要将选中的数据,转化成id手动定义数据结构let data = [{ // 规格名称,可修改 kindName: "二级规格", customValue: "", // 已选中 specificationsName: ["测试","测试2"], dialogVisible: false, // 默认所有的数据,未选中和已选中的数据都在里面 defaultSpecificationsName: [ { id:1, name: "测试", }, { id:2, name: "测试2", child:[ { kindName:"测试2", customValue:"", specificationsName:["测试3"], dialogVisible:false, defaultSpecificationsName:[ { id:3, name:"测试3" } ] } ] } ] }]递归函数写成公共递归函数,可根据name获取id,也可以根据id获取name,方便提交数据。let traversalIds = (setValues,value) => { // setValues 传递的data数组,value是参数,若是需要获取id,则传入的是name,反之。 setValues.forEach(item => { let specificationName = [] item.specificationsName.forEach(o => { item.defaultSpecificationsName.forEach(i => { if(i.child && i.child instanceof Array){ onTraversalIds(i.child,value) } if(o === i[value]){ // 判断specificationsName中的id或name是否等于 specificationName.push(i[value]) } item.specificationsName = specificationName // 修改某数据下的specificationName }) }) }) return setValues // 将以修改的数据返回 }平级数据将所有选中的数据,添加至一个数组中,pid是关联父idlet TraversalArray = (setValues,pid) => { let specifications = [] for(let index = 0;index < setValues.length;index++){ const data = setValues[index] data.specificationsName.forEach(name => { data.defaultSpecificationsName.forEach(item => { // 判断name是否相等 if(name == item.name){ // 若是相等,则添加至数组中 specifications.push({ id:item.id ? item.id : "", pid:pid, name:item.name }) // 循环数组,若是没有pid,将pid删除 specifications.map(o => { if(!o.pid){ delete o.pid } }) // 终止结束 return } // 判断是否有child if(item.child && item.child instanceof Array){ // 重新调用此函数,并将父id传递到此函数中 const obj = TraversalArray(item.child,item.id) // 判断返回的数据是否是数组 if(obj instanceof Array){ // 如果是合并两个数组,并将合并的数组返回 specifications = [...specifications,...obj] return specifications } } }) }) } return specifications }
2021年04月09日
104 阅读
0 评论
0 点赞
2021-04-09
setState为什么是异步?
笔者曾一直以为setState是异步的,并非是同步的,直到前一阵子同事问我React中的setState是异步还是同步.....为什么要这么做1. 保证内部的一致性即使state是同步更新,props也不是。(只有在父组件重新渲染时才能知道props)2. 性能优化将state的更新延缓到最后批量合并再去渲染对于应用的性能优化是有极大好处,如果每次的状态改变都会去重新渲染真实的dom,将会带来巨大的性能消耗。原理解释setState并不是真正意义上的异步操作,只是模拟了异步的行为,其实官方已经给出答案,setState并不是真正的异步class App extends Component { state = { count: 0 }; componentDidMount() { // 生命周期中调用 this.setState({ count: this.state.count + 1 }); console.log("lifecycle: " + this.state.count); setTimeout(() => { // setTimeout中调用 this.setState({ count: this.state.count + 1 }); console.log("setTimeout: " + this.state.count); }, 0); document.getElementById("div2").addEventListener("click", this.increment2); } increment = () => { // 合成事件中调用 this.setState({ count: this.state.count + 1 }); console.log("react event: " + this.state.count); }; increment2 = () => { // 原生事件中调用 this.setState({ count: this.state.count + 1 }); console.log("dom event: " + this.state.count); }; render() { return ( <div className="App"> <h2>couont: {this.state.count}</h2> <div id="div1" onClick={this.increment}> click me and count+1 </div> <div id="div2">click me and count+1</div> </div> ); } }探讨前,我们先简单了解下react的事件机制:react为了解决跨平台,兼容性问题,自己封装了一套事件机制,代理了原生的事件,像在jsx中常见的onClick、onChange这些都是合成事件。那么以上4种方式调用setState(),后面紧接着去取最新的state,按之前讲的异步原理,应该是取不到的。然而,setTimeout中调用以及原生事件中调用的话,是可以立马获取到最新的state的。根本原因在于,setState并不是真正意义上的异步操作,它只是模拟了异步的行为。React中会去维护一个标识(isBatchingUpdates),判断是直接更新还是先暂存state进队列。setTimeout以及原生事件都会直接去更新state,因此可以立即得到最新state。而合成事件和React生命周期函数中,是受React控制的,其会将isBatchingUpdates设置为 true,从而走的是类似异步的那一套。在 setTimeout 中去 setState 并不算是一个单独的场景,它是随着你外层去决定的,因为你可以在合成事件中 setTimeout ,可以在钩子函数中 setTimeout ,也可以在原生事件setTimeout,但是不管是哪个场景下,基于event loop的模型下, setTimeout 中里去 setState 总能拿到最新的state值。总结setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。setState的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次 setState , setState 的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新。
2021年04月09日
38 阅读
0 评论
0 点赞
2021-04-09
JavaScript闭包的理解
什么是闭包(Closure)简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。MDN 上面这么说:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。作用域要理解闭包,就得理解Javascript函数作用域。作用域无非就两种:全局作用域和局部作用域看下面一个例子 var a = 2 // 全局作用域 function foo(){ var a = 3 // 局部作用域 console.log(a) // 使用局部作用域中的变量 a,则输出2 } foo() console.log(a) // 使用全局作用域中变量 a,则输出3根据作用域的规则,引擎会从当前执行的作用域开始查找变量,如果找到,则使用该变量,如果找不到,就向上一级继续查找,直到抵达最外层的全局作用域时,无论找到还是没找到,查找的过程都会停止。 var a = 2 function foo(){ console.log(a) //使用全局作用域中的变量 a,所以输出的是2 } function foo(){ var a = 2 } console.log(a) //无法访问foo()作用域中定义的量变a,全局作用域又未定义变量,因此输出的是ReferenceError: a is not defined变量 a 在全局作用域下定义,则全局作用域下的局部作用域内的执行代码或者说是表达式都可以访问到变量 a 的值。局部变量里的同名变量(a)会截断对全局变量 a 的访问,因此在调用函数 foo()时会输出2。JavaScript作用域限制了普通方法是无法让外层作用域访问到内部作用域,因此在全局中输出变量a会是3。 var a = 2 // 全局作用域 function foo1(){ var a = 3 // 局部作用域 function foo2(){ console.log(a) //使用的是 foo 的局部变量,所以输出的是3 } return foo2 } var result = foo1() result() //输出的是3闭包是如何产生的?实际上,上一节代码中的 foo1函数,就是闭包。 简单来讲,当函数外部能访问函数内部时,产生的就是闭包。我理解的是,闭包就是能在全局作用域调用局部作用域,所以闭包就是将函数外部和函数内部连接起来的一座桥梁。闭包的用途闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。在正常情况下,我们在外部时无法修改函数内部变量的值: function print(x) { var _internal = 1; console.log(_internal + 1); } print(1); // 2 // ... print(1); // 2我们可以看的,无论print()调用多少次,输出的值都是2,_internal的值是1这是因为 JavaScript 中的垃圾回收机制,在多次调用 print() 时,每一次都需要回收前一次的内存,之后再次申请新内存,因此 _internal 无法在内存中继续保存。那我们如何保存值,那就是使用---闭包 var add function print() { var _internal = 1; add = function(x) { _internal += x; } return function log() { console.log(_internal); } } var test = print(); test(); // 1 add(1); test(); // 2经过上述可以看出,函数 print() 在经过 add() 运行之后,_internal 的值分别为 1 和 2,这就说明了 _internal 始终保存在内存中,并没有在 var test = print(); 调用时被回收。这是因为 print() 内的 log() 作为返回值,被赋给 test 这个全局变量,因此 log() 始终在内存中。而 log() 依赖 print() 并且可以访问 _internal,所以 print() 也始终在内存中,而且在 var test = print(); 调用时没有被回收。换而言之,当 _internal 在声明的时候分配了内存,我们可以将其内存地址表示为 0x...1,在 print() 函数被调用之后应该会被回收,但是由于上述原因,没有被回收,它的值将继续保留在地址为 0x...1 中。在外部可以使用指针去寻址,并取得其值。闭包的弊端内存泄漏:由于闭包会使得函数内部的变量都被保存在内存中,不会被销毁,内存消耗很大。因此需要在退出函数之前,将不使用的变量都删除。会修改函数内部变量的值。参考链接学习Javascript闭包(Closure)理解闭包讲清楚之javascript作用域
2021年04月09日
131 阅读
1 评论
1 点赞
2021-04-09
在React Native项目中使用fastlane打包apk以及ipa
开发过程中经常遇到多个环境切换的问题,手动切换比较麻烦,使用 fastlane 可以快速切换到不同的 env,打包发布的时候可以有时间来上一杯 ☕️,解放这无处安放的
2021年04月09日
34 阅读
0 评论
0 点赞
1
...
5
6
7