-
Notifications
You must be signed in to change notification settings - Fork 257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React 最佳实践 #6
Comments
This was referenced Feb 1, 2016
亲,应用层开发怎么不写了呢? |
redux store的数据组织,我有个问题?如果page1 和 page2 这两个页面里面有一个card里面的数据是相同事,那这个card store是该设计在page 1 ?page2?里面 还是该独立出来的啊? |
@ClarenceC 如果只是这两个页面复杂,放到任何一个,在另一个页面直接 |
是不是这样: |
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
组件化开发
componentDidMount
而不是didMount
或mounted
呢?类似的还有超长的dangerouslySetInnerHTML
有考虑过键盘的感受吗。其实这是一种古老的命名策略,给不鼓励使用的方法设置非常长的方法名,来尽量避免使用。生命周期方法都是给你应急或与外部组件对接用的,如果能避免就尽量不用。一个 UI 组件的完整模板
应用层开发
长痛不如短痛,如果你预料到业务未来会比较复杂的话,还是早点使用 Redux 吧。但即使使用了 Redux 并不是说只有一种选择,基于它上面的生态非常丰富。Redux 是一个重思想轻实现的框架,理解思想非常关键。
下图是我画的 Redux 操作流程图
有几点明确一下:
type
来区分connect
方法把 Store 中数据按需绑定到 View 上,是最核心方法之一,有很多的细节,建议看下源码Redux 开发常用的问题
使用 Redux 时,最可能遇到了是这些问题
一、数据如何组织
好的数据组织方式评判方法很简单:一眼就知道这个数据是哪个页面、哪个模块、大致做什么的。
现在大多是单页面应用,而且每个页面(Page)包含多个模块(我喜欢叫卡片 Card),所以这个数据树至少会包含 page 和 card 两层。在我开发的一个应用中,是这样来规划的
左边是页面大致的结构,包含可能多页面复用的全局筛选器(Global Filter),当前页面的多个卡片。所以在设计 Store 结构的时候就分了 page 和 card 两层,card 下面才是业务数据。为了让全局筛选器统一管理,单独在顶层开辟了
filters
分支。二、性能
只要你使用了 immutable 的数据结构后,做 Redux 性能优化非常简单。由于
connect
默认开启了 pure render 模式,所以让需要数据的组件来 connect 数据性能最好,也就是** connect at lower level**。下图演示了在不同位置 connect 导致 render 的差异。第一棵树中红色结点数据变化后
connect
所有数据,然后 props 形式把数据往下传,渲染结果如第二棵树,从顶层直到数据改变的组件都会渲染connect
,其它地方就不需要关心这块数据,结果只有改变数据的组件被渲染,结果如第三棵树另外你还可以对 Component 添加 pure-render-decorator 来提升组件渲染性能。对于速度慢的函数使用 Memoization 来提升性能,常见的有 lodash.memoize
三、复用
首先要清楚,不要用了复用性而牺牲了开发的便利性,而且复用在最初是比较高效的,但可能随意业务的扩展,本来相同的东西变得不同,这时候最初的复用反而给未来增加了成本。我不是不鼓励复用,只是不建议把它摆在太高的位置。
View 的复用比较简单,只要保证 view 的纯粹,在
connect
之前可以当作标准的 react 组件任意复用。如果想把 view, action, reduer 做为一个整体的业务模块来考虑复用,是比较难的。但这其实是最能提升效率的。如果你也遇到这样的场景,可以试下这个方法。generateView
方法,接收页面名(page)和卡片名(card)来生成 view 和 actiongenerateReducer
方法,接收同样的页面名(page)和卡片名(card)来生成 reducer因为两个方法的 page 和 card 是一致的,这样就能保证它们互相引用没问题且和现有的不冲突。
这样复用一个业务组件就是复用这两个方法。
示例代码如下:
四、异步处理
以上四点业务层的经验是我一年多以来感受比较深的。还有目录组织、路由等一些细节问题,可参考的资料很多就不赘述了。
The text was updated successfully, but these errors were encountered: