ComponentKit 和 FLUX 架构 - 避免不必要的重新渲染 UI
ComponentKit and FLUX architecture - avoid unnecessary re-rendering of the UI
我正在使用 Facebook ComponentsKit 生成我的视图。
我现在正在迁移到 "flux" 架构以更改应用程序状态和触发视图更新。
我遇到的主要问题是并非所有状态更改都应触发 UI 更新。我不明白避免这种情况的 "generic" 机制。
基本上,应用程序状态是 "big" "JSON",表示 "view model"(已解析为本机类型对象)。 JSON 包含所有视图声明及其初始值。 (JSON 比较复杂)
例如,简化的 JSON 表示包含 "pager" 组件和导航 "next" 按钮的视图层次结构:
{
... views ...
{
"pager" : {
"id" : "pager-id-xxx",
"currentPage" : 0,
"pages" : [
....pages....
{},
{},
....pages....
]
},
...
"navigation-next-button" : {
"id" : "navigation-next-button-id-xxxx",
"target" : "pager-id-xxx"
}
},
... views ...
}
我的 "Flux" 抽象看起来像:
// "Action" portion
@interface ChangePageAction
@property id destinationId; // very simplified action. wraps the destination "id"
@end
@implementation ChangePageReducer
-(JSON)reduce:(JSON)initialJSON action:(ChangePageAction *)changePageAction {
// the "reduce" portion finds the node of the pager (in the JSON) and changes the value by +1
// something like:
// find the node in the JSON with the changePageAction.destinationID
Node *nodeCopy = getNodeCopy(initialJSON,changePageAction.destinationId);
replaceValue(nodeCopy,nodeCopy.currentPage + 1);
// according to FLUX doctrine we are supposed to return a new object
return jsonCopyByReplacingNode(nodeCopy); // a new JSON with the updated values
}
// the navigation button triggers the new state
@implementation NavigationNextButton {
id _destination; // the target of this action
FluxStore _store; // the application flux store
}
-(void)buttonPressed {
ChangePageAction *changePage = ...
[_store dispatch:changePage];
}
@end
在我的 "view controller" 中,我现在收到 "update state" 回调
@implementation ViewController
-(void)newState:(JSON)newJSON {
// here all of the view is re-rendered
[self render:JSON];
//The issue is that I don't need or want to re-render for every action that is performed on the state.
// many states don't evaluate to a UI update
// how should I manage that?
}
@end
不幸的是,在 ComponentKit 中没有简单的方法可以做到这一点。 React 有 shouldComponentUpdate
,但 ComponentKit 没有等价物。
好消息是 ComponentKit 应该足够聪明,可以重新构建所有组件,然后意识到实际上什么都没有改变,最终不会对 UIKit 进行任何更改。
坏消息是它会花费相当多的 CPU 时间。
我正在使用 Facebook ComponentsKit 生成我的视图。
我现在正在迁移到 "flux" 架构以更改应用程序状态和触发视图更新。
我遇到的主要问题是并非所有状态更改都应触发 UI 更新。我不明白避免这种情况的 "generic" 机制。
基本上,应用程序状态是 "big" "JSON",表示 "view model"(已解析为本机类型对象)。 JSON 包含所有视图声明及其初始值。 (JSON 比较复杂)
例如,简化的 JSON 表示包含 "pager" 组件和导航 "next" 按钮的视图层次结构:
{
... views ...
{
"pager" : {
"id" : "pager-id-xxx",
"currentPage" : 0,
"pages" : [
....pages....
{},
{},
....pages....
]
},
...
"navigation-next-button" : {
"id" : "navigation-next-button-id-xxxx",
"target" : "pager-id-xxx"
}
},
... views ...
}
我的 "Flux" 抽象看起来像:
// "Action" portion
@interface ChangePageAction
@property id destinationId; // very simplified action. wraps the destination "id"
@end
@implementation ChangePageReducer
-(JSON)reduce:(JSON)initialJSON action:(ChangePageAction *)changePageAction {
// the "reduce" portion finds the node of the pager (in the JSON) and changes the value by +1
// something like:
// find the node in the JSON with the changePageAction.destinationID
Node *nodeCopy = getNodeCopy(initialJSON,changePageAction.destinationId);
replaceValue(nodeCopy,nodeCopy.currentPage + 1);
// according to FLUX doctrine we are supposed to return a new object
return jsonCopyByReplacingNode(nodeCopy); // a new JSON with the updated values
}
// the navigation button triggers the new state
@implementation NavigationNextButton {
id _destination; // the target of this action
FluxStore _store; // the application flux store
}
-(void)buttonPressed {
ChangePageAction *changePage = ...
[_store dispatch:changePage];
}
@end
在我的 "view controller" 中,我现在收到 "update state" 回调
@implementation ViewController
-(void)newState:(JSON)newJSON {
// here all of the view is re-rendered
[self render:JSON];
//The issue is that I don't need or want to re-render for every action that is performed on the state.
// many states don't evaluate to a UI update
// how should I manage that?
}
@end
不幸的是,在 ComponentKit 中没有简单的方法可以做到这一点。 React 有 shouldComponentUpdate
,但 ComponentKit 没有等价物。
好消息是 ComponentKit 应该足够聪明,可以重新构建所有组件,然后意识到实际上什么都没有改变,最终不会对 UIKit 进行任何更改。
坏消息是它会花费相当多的 CPU 时间。