React hooks 简单介绍
想第一时间获取我的最新文章,请关注公众号: 技术特工队
React Hooks 产生的原因
在平时的React开发中,我们常用的是使用 Class 来封装一个组件,这也是我们常常使用的方法,看似使用起来很好用,很方便的,那有没有一些让你不舒服的地方呢? 让我们往下看。
改造成本大
封装一个组件常常使用Class类来进行,如果够简单很普通的组件,就只有一个render函数,通常这种会被直接写成函数组件,如下所示:1
2
3export function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
上面的组件其实等效于下面的class1
2
3
4
5class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
但如果我们使用的函数式组件,这时候如果需要在组件内不得不加状态时,我们就必须把函数式组件改造为class 类型的组件,才能满足我们的需求,如果对于很多的函数式组件,那这是致命的,会产生很大的工作量及不稳定的因素在里面了。所以想要复用一个有状态的组件太麻烦了!
React 中 State 的那点事
想第一时间获取我的最新文章,请关注公众号: 技术特工队
setState 为什么是异步的
首先我们先来看一个例子:1
2
3for ( let i = 0; i < 100; i++ ) {
this.setState( { num: this.state.num + 1 } );
}
如果每次都立马执行的,再短短的时间里,会有100次的渲染,这显然对于React来说是很大的一个渲染性能问题,所以针对setState做了一些特别的优化:React会将多个setState的调用合并成一个来执行,这意味着当调用setState时,state并不会立即更新
具体来说是在 setState之后并不会立马执行,而是放到一个队列中,在合适的时机,批量更新state,队列机制可以批量的合并更新State。
最终被react合并后效果如下:1
2
3
4
5
6
7Object.assign(
previousState,
{ num: this.state.num + 1 },
{ num: this.state.num + 1 },
{ num: this.state.num + 1 },
...
)
再看这个例子:
1 | const b = { name: 'brian', name: 'peter' , name: 'Dave'}; |
这个问题也就解释了,上面的循环逻辑执行,每次拿到的 this.state.num 始终是0,最值在最后合并后,num的值再变为1 ,所以对于react内部渲染最终只会执行一次最终的渲染,因为这部分React将其进行了合并处理。
React native 中原生层与js数据交互的几种方式
想第一时间获取我的最新文章,请关注公众号: 技术特工队
RN 方法的调用的几种方法
从数据的交互上来看,调用方无非从 native 调用 js 层,或 从 js 调用 native 方法,常用的主要是通过 JavaModule
来提供方法调动,但常常我们有一些自定义的native view,而这部分也是需要和 js进行相关的交互,那么下面进行调用的一些统一的整理。
js 调用 native 方法
js 通过 JavaModule
方式进行调用。
在 RN 中需要调用 native 的方法,常用的是通过在 native 继承 ReactContextBaseJavaModule
然后注册 ReactMethod
方法,供js层进行调用。
例如:
1 | public class ToastWidget extends ReactContextBaseJavaModule { |
然后此 module 在 ReactPackage 中进行注册,最后此package在 Application 中进行注册处理。
在 js 中 可以按如下方式即可调用 native 层的方法。
1 | import { NativeModules } from 'react-native' |
OSX AutoLayout原理介绍
想第一时间获取我的最新文章,请关注公众号: 技术特工队
AutoLayout介绍
Auto Layout 是苹果公司在iOS6发布的界面布局技术,为了适配不同大小屏幕及屏幕变化而推出的一种技术方案,旨在实现一次编写布局界面UI,自动适应所有屏幕布局,并随着iOS SDK的迭代逐步完善了各种布局API、提供多种使用Auto Layout的布局方式。实际上Auto Layout算法本身并非有Apple发明,Auto Layout源于Cassary约束解析工具包。该算法由Alan Borning、Kim Marriott、Peter Stuckey、Yi Xiao于1997年发布,该算法的主要思想是:将基于约束系统的布局规则(本质上是表示视图布局关系的线性方程组)转化为表示规则的视图几何参数。
传统的布局
frame 布局
传统的布局方式是基于Frame来做UI控件的界面布局的,即设置控件在父视图中的起始坐标点Origin(x,y)和控件的大小Size(width,height),为了精确,我们必须计算每个视图的frame。但布局一旦发生变化,相关frame都需要重新计算。然后这些计算都需要不断的手动动态的去计算,导致一旦有变化,就会需要去维护和调试。
自动缩放(auto resizing)
自动缩放的出现在一定程度上减轻了我们的负担。自动缩放规定父视图的frame变化时,视图的frame如何应对。如此一来,简化了布局响应外部变化所需的工作。但是他仅能应对外部父布局的变化,自身大小的变化则无法进行处理。
OSX 开发知识点汇总(五)
想第一时间获取我的最新文章,请关注公众号: 技术特工队
TableView
在 OSX 中有一些列表的需求,这时候需要使用 OSX 中 TableView 来实现,但是这个 TableView 与 Android的 ListView 不太一样。使用还是比较复杂的。下面做一个简单的介绍,
TableView 的使用
首先需要在布局文件中,拖出一个TableView,并且添加相应的每列的数据源,主要是 使用
TableCellView
, 里面默认的控件有一个TextFiled
和一个ImageView
,如果需要其他控件则需要自己进行自定义进行实现,下一小节会说到。需要对 TableView 设置一个数据源,需要实现
NSTableViewDataSource
接口, 并对TableView
设置数据源,如下:1
2
3
4
5
6
7tableView.dataSource = self
extension MainView: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return dataSources.count
}
}对每行的数据进行渲染处理,设置
delegate
和target
代理,并实现NSTableViewDelegate
接口中如下方法
OSX 开发知识点汇总(四)
想第一时间获取我的最新文章,请关注公众号: 技术特工队
OSX 中Window中常用的一些属性
1. applicationShouldTerminate
在 AppDelegate 中,复写applicationShouldTerminate
方法可以达到控制是否点击关闭按钮是否关闭应用的效果,其返回值TerminateReply
有三个值,具体如下:1
2
3
4
5public enum TerminateReply : UInt {
case terminateCancel // 取消掉关闭,等于点击无作用
case terminateNow // 现在直接关闭
case terminateLater // 暂且不关闭
}
在下面的返回值可根据一些条件进行判断,比如有些应用点击关闭按钮是仅将窗口关闭,并最小化应用不退出,则可以根据设置情况进行返回不同的值。1
2
3func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
return .terminateNow
}
2. applicationShouldTerminateAfterLastWindowClosed
在 AppDelegate中 applicationShouldTerminateAfterLastWindowClosed
中的作用为确认是否是等待所有窗口关闭后才关闭整个应用的作用。
1 | func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { |
OSX 开发知识点汇总(三)
想第一时间获取我的最新文章,请关注公众号: 技术特工队
NSStackView
OSX 中 NSStackView 使用自动布局(系统的自动布局特性)来根据你的要求管理和对齐一组视图。可以设置为 水平方向,或者垂直方向。如下:1
2stackView.orientation = .horizontal //水平方向
stackView.orientation = .vertical //垂直方向
添加子view
为stackView 中添加 子view的方式如下:1
stackView.addArrangedSubview(view)
注意: 由于stackView 是继承自 NSView, 所有也会有 addSubview(view)
的方法,但是调用此方法,不会自动扩大 stackView 的宽高,而导致新加的view 显示不出来。
移除子view
移除子 View 采用如下方式:1
2stackView.removeArrangedSubview(view)
view.removeFromSuperview()
注意:子view从stackView移除后,还必须将子view从父view中移除
iOS UIWindow 覆盖 StatusBar
最近产品要做一个消息的通知,而且通知是覆盖在 StatusBar 上面的。如果是普通的 UIView 则肯定是不行的,因为 StatusBar 为系统全局性的视图,所以要想覆盖它,则必须为 Statusbar 类型的,那么也就是 UIWindow 了。
UIWindow 的基础介绍
- UIWindow是一种特殊的UIView,通常在一个app中至少会有一个UIWindow。
- iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的View,最后将控制器的View添加到UIWindow上,于是控制器的View就显示在屏幕上了。
- 一个iOS程序之所以能显示在屏幕上,完全是因为它有UIWindow,也就是说,没有UIWindow就看不到任何UI界面。
- 状态栏和键盘都是特殊的UIWindow。
这里有三个重要的对象UIScreen,UIWindow,UIView。
- UIScreen对象识别物理屏幕连接到设备
- UIWindow对象提供绘画支持给屏幕
- UIView执行绘画,当窗口要显示内容的时候,UIView绘画出他们的内容并附加到窗口上。
OSX webview 与 native 通信简单介绍
想第一时间获取我的最新文章,请关注公众号: 技术特工队
在开发混合应用中,经常需要 js 与 webview 进行通信,那么官方也提供了一些方法进行消息处理,今天这里介绍一款开源库来更好的解决的 native 与 js 通信的问题,也就是 WebViewJavascriptBridge
基本配置使用
- 在 Podfile 文件中添加库稳健配置
pod 'WebViewJavascriptBridge', '~> 6.0'
,然后执行pod install
使 WebViewJavascriptBridge 初始化与 Webview 进行绑定
1
let bridge: WebViewJavascriptBridge = WebViewJavascriptBridge.init(forWebView: webview)
在js层中进行注册处理
1
2
3
4
5
6
7
8
9
10
11// 将该方法写入 javascript 中
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}经过上面的步骤,基本的搭建就完成了,下面就是要相互注册调用的函数,以及互相调用的方法。
- native 层注册方法供 js 调用,以及 native 层调用的js方法。