最近在折腾react,因此,将一些本身碰到的问题以及对应的解决办法分享出来,期待和你们共同探讨和进步!
react折腾系列之一:如何在ant框架下,Form表单中实现getFieldDecorator包装控件的按需加载。react
文笔有限,代码才是程序员的真爱。相信看完下方的几行简单的代码和其中的注释,你们对本文要描述的问题,会有比较清晰的了解。git
ps:固然,不少状况下,你可能只须要实现路由组件的按需加载即可,无需涉及这么精细化的小组件操做,那么请不要纠结,本文偏重技术问题探讨,至于应用场景,可灵活自行抉择。程序员
问题清晰了,那么接下来着手解决以前,得有个大概的思路:github
针对该问题,其实比较难找到对应的资料和实例(可能确实这样的需求很少吧)。因此只能自行撸代码了,其实粗略想一想,应该不难,找个现成的react延迟加载组件还不容易啊。相信这个难不倒你们,接下来以你们比较熟悉的react-loadable为例。shell
代码大体以下,比较简单,也不须要注释了,具体可查看官方文档和实例。缓存
代码撸完,跑起来看看,不看不知道,一看吓一跳。。。bash
必须解决是否是网络
so,react-devtools看一下:框架
看起来,一切正常,该有的props和state都有啊!编辑器
好吧,没办法,又找不到现成的资料和项目参考。看来只能放大招了,看源码!
上面,是react-loadable的一部分源码。因此,ant中的getFieldDecorator包装后,一旦Form中的任何一项组件(Input之类的)值改动(onchange),Form要更新,便会引发全部组件从新生成。
对应到react-loadable的代码,即是:任何一个控件(例如Input)触发onchange,Form更新,全部控件从新进constructor,执行对应的init,而后render,第一次render进第一个if,第二次render进第二个if。
验证很简单,在react-loadable的render方法中,把state打印出来:
this.state-- {error: null, pastDelay: true, timedOut: false, loading: true, loaded: null}
this.state-- {error: null, pastDelay: true, timedOut: false, loading: false, loaded: Module}复制代码
重点看loading和loaded字段,每次onchange都会经历一次loading从true到false的过程。
看完react-loadable源码,问题理清楚后,大招不能停,解决思路:
代码以下,挺简单的改动,每次加载完的组件,存起来,重复使用。
虽然react-loadable也进行了缓存,可是只是进行了网络请求缓存,每次都会从新走load流程,只是第二次过程很快而已,而解决的思路是直接进行组件缓存。
因为掘金的富文本编辑器复制后换行失效,若是须要看此处源码的,能够点击此处查看
能够考虑本身造一个自己就支持组件级别缓存的loadable组件,并且react-loadable自己的源码有三百多行,可能有挺多咱们不须要的功能。
因为掘金的富文本编辑器复制后换行失效,若是须要看此处源码的,能够点击此处查看
用起来也方便:
import loadable from './my-loadable'
function getLoadableComponent(componentName) {
return loadable(() => import('../form-items/' + componentName), null, null, componentName)
}
export default getLoadableComponent复制代码
码字不易,以为此文对你有帮助的,麻烦点个赞鼓励鼓励。