消费 web API 来做呈现,所以有了客户端软件,就像 iOS SDK 里的组件会通过 web API 获取信息, 然后展示在屏幕上。
react 与 angular 的区别,可以从它们对于 HOC (高阶组件) 的使用上看到。 HOC 这种东西显然是诞生于特定的编程模型的。
故而 angular 既没有 HOC 又没有纯函数的概念,因为它没有采用 js the good part 之外的方面,而仅仅是把 js 当作 java 在使用似的。
react 从 jsx 开始,让一个组件的渲染机去渲染一个组件的状态机,然后通过外部条件对于此组件状态机的改变(准确地说,是对此组件的状态机的扩充),让此组件的渲染机能渲染出来的数据 越来越多。
这些数据来自 render props 和 HOC 。 render props 的用法是简单的, HOC 的用法是简单又友好的,至少对于开发者来说是这样的。
如果说整个的 HOC 机制和 setState 机制都是 react SDK 里的一个提供(推广),那么为什么 angular SDK 没有 HOC 呢?既然 angular 也是 js 。为什么 iOS SDK 里没有 HOC 呢?它们可都是客户端开发。这是我的一个疑惑。
angular SDK 里对于组件能渲染出那些数据是明确的,在组件通信方面 它并没有用到 状态提升
也没有用到 而是直接用了 service 订阅模式。
在 react SDK 中,状态提升的滥用是非常容易的, props drilling 也是因为组件之间共享数据是如此简单才会出现的,以及之后的 context 、useContext useReducer useMemo (显然它是为函数组件增加能力的),以及在数据更新与通知机制订阅机制方面的 redux recoil 。
在 react SDK 中,函数组件更像一个 partial (可以渲染变量的一个文件片段, 这个概念是远古 PHP 和静态站点生成器的概念),而且这个 partial 的 rerender 数应该是越低越好的。谁来控制 partial 的 rerender ? 这篇文章1里有提到。
我的理解是,一个 partial 的重新渲染一定是因为它被判断是(就它负责渲染的数据而言)有了新数据值 所以它才要重新渲染的。一旦没有新值,那么它就不需要重新渲染。如果在没有新值的情况下重新渲染了,那么就等于出现了 rerender 问题,这是可以优化的。
在 react SDK 中,这样的 partial 被叫做 dummy component (只负责渲染 props 里的东西) 也可以叫做 presentational component ,而且还有了 stateful dummy component 和 stateless dummy component 的概念。然后就不可避免地再次(在接受了 “简单又友好” 的情况下)走到组件通信机制,而在组件通信机制里 稍有不慎就会触发 rerender 问题。
比如表格,表格状态该如何向表格记录者来提交表格呢?如果搜索子组件如何向父组件通信 react child state to parent communication 那么会得到这样的答案。这里有三个考量:1 尽量不触发 rerender 问题(即不该 rerender 的组件 不要重新渲染,不要放在一个组件的渲染机制里) 2 尽量不引入第三方库 3 你能用的只有事件 而事件做了两件事情 第一在订阅机制下和你感兴趣的数据源进行交互--这是改变数据源的而数据源的改变会触发所有订阅了此数据源的组件的正当的“自我刷新” 第二更新自己的 state -- 这是本组件内的 presentational 的 stateful 的。最后我的发现是: 1 state props pass down 是一个几乎不能用的东西 2 父组件 子组件 本应该是两个平行组件 它们的渲染机制不应该缠绕在一起(即 不应该由父组件渲染出子组件,这会引起 rerender 问题)(应该是 在一个 dummy component container component 里垒组件,各组件拿到各自数据做各自的渲染:这会几乎杜绝 rerender 问题,因为你的 rerender 只会来自 render 你的那个组件的状态变化(现在好了,它不包含状态) or 你订阅的数据的更新 可以来自 context 或 redux 或 recoil whatever ) 3 所谓的 单向数据流 React is all about data flowing down the component's tree, never up. 只适合那些永远不会变化的数据或(静态站点生成器里的)填充 slot 的数据,而不会是真正变化的数据(真正变化的数据 要么来自 props 要么来自订阅机制) 4 解决 props drilling 的最好办法就是不嵌套组件 尽可能多写平行组件,因为平行组件嘛 没有 props 的传递了,自然就不会有 props drilling 。
最后 一张图片 1 提醒自己关注 rerender 问题和其它性能问题。
最后 接下来要看的是 angular 如何处理表格1,在没有高阶组件也没有组件嵌套的情况下,没有 HOC 又没有纯函数,在什么都没有的情况下。我预想的是 肯定是将组件间通信量降低到最低,在订阅机制下,让每一个组件订阅自己的数据源 然后由事件触发数据源更新、触发订阅者的更新:触发所有订阅了此数据源的组件的正当的“自我刷新”。
组件嵌套是这样的
<tbody>
{
todos.length > 0 && todos.map((todo, i) => {
return <TodoRow todo={todo} id={i+1} key={`${todo.title}${i}`} {...props} />
})
}
</tbody>
没组件嵌套是这样的
9 <tbody *ngIf="array.length!==0"><!--这里我们判断一下传递过来的数组是否为空,如果是空的话我们就没有必要渲染出来了-->
10 <tr *ngFor="let data of array">
11 <td>{{data.xcood}}</td>
12 <td>{{data.ycood}}</td>
13 <td><button type="button" class="btn btn-default" (click)="delete(data)">删除</button></td>
14 </tr>
15 </tbody>
1
2
3 ngFor
4 ngFor dynamic table with angular service
5 没有嵌套组件的世界是多么单纯美好,也没有 props 乱传,也没有 rerender 乱渲染,更没有不必要的父组件子组件的通信机制和 render 传染,一切都是订阅机制下的平行组件 react 官方所倡导的就是低性能的 rerender 问题爆棚的做法 只不过数据太少导致问题显现不出来而已。
在大型项目中,对 React 不熟悉的情况下很容易写出难以维护或性能低下的代码
https://zhuanlan.zhihu.com/p/29103532
state manager: 从 A component 接受改变状态的信息 重新渲染所有受影响的 component
https://zhuanlan.zhihu.com/p/150395461
在使用嵌套组件和 HOC 的 react SDK 的情况下,
目前我认为 拆分 context 其实是比较好的做法, 因为它是 react 自带的
而且有明确的优化办法 用 useMemo
https://medium.com/swlh/avoid-prop-drilling-with-react-context-a00392ee3d8
https://blog.axlight.com/posts/4-options-to-prevent-extra-rerenders-with-react-context/
useMemo 的原理
https://segmentfault.com/a/1190000039405417
说不定我以后可能有一天再也不用和 react SDK 打交道了,我深深感觉到那时候我在它这里学到的一切都将因为 HOC 的推广率太低而无处可用。 angular 没用到 HOC, iOS 客户端开发没用到 HOC 。
// 当然 在订阅机制(组件通信)这方面还是相通的。嵌套组件别用太多就是了(嵌套组件那套:嵌套组件、HOC、函数组件)
// 当然 在订阅机制(组件通信)这方面还是相通的。嵌套组件别用太多就是了(嵌套组件那套:嵌套组件、HOC、函数组件,在 react 圈子里很流行,在整个编程模型里 很小众 它是很小众的编程模型, 无论结出多么奇异的果)
HOC 详解(网友发言, 支持HOC和反对HOC的 即使在react圈子里也可以反对HOC): 为什么 angular 里没有 HOC 1 2 3 4! 怀念没有HOC时候的单纯美好 同样是 web 客户端的 SDK 哦
一方面看看 web 客户端怎么写,一方面看看不使用 HOC 那套的情况下怎么写 web 应用
0
文章收集
- 解释了工具 recoil get 是什么 1
- 解释了渲染器为什么会触发组件重新渲染、渲染过程包括什么,对于渲染过程里的 diff 函数执行结果: 如何根据 diff 结果 对待上一次总渲染结果 1 diff in react
- 工业级算法 React、Vue2、Vue3的三种Diff算法 1
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。