likes
comments
collection
share

记录 Backbone 项目中引入 React 组件的一个问题

作者站长头像
站长
· 阅读数 13

一、背景

测试同学发现了一个线上问题,表单项里面有一个选择框没有渲染出来,排查之后发现这个选择框是引入的React组件,没有正确渲染出来。项目使用的是Backbone框架,在其中某些位置引入React组件并挂载到相应的Dom节点上。

二、问题排查

  1. 测试反映的问题是在表单的编辑场景,表单项A的选择框没有渲染出来, 进入系统发现可以稳定复现。
  2. 顺便检查了一下表单的新建状态,发现表单的新建状态,表单项A的选择框正确渲染了。
  3. 检查表单新建状态和编辑状态的区别。表单的编辑状态的区别就是带入了一些数据,有的数据是本地缓存的,有的数据是接口请求返回的。然后分别在这两个部分debug。
  4. 带入本地缓存数据的部分,数据的引用和赋值都没有什么问题。带入接口请求返回数据的时候,在请求响应前后,分别打debug。发现在请求响应前,表单项A的选择框是渲染了的,请求相应之后,表单项A的选择框又消失了。
  5. 问题定位在了请求响应之后所做的操作中。请求响应之后将返回的数据写在了表单对应View视图的Model模型中。
  6. Backbone中,View中Model更新之后,会触发view的重新渲染,查阅资料之后确实是在重新渲染的时候出现的问题。

三、问题分析

记录 Backbone 项目中引入 React 组件的一个问题

这个是表单原来的大致渲染逻辑

  • 表单项B 和 表单项A 都是在 onShow 的时候渲染到页面上的React组件
  • 表单项B 的接口数据返回之后setModel
  • 表单Model更新后触发 onRender,此时页面模板重新渲染,之前渲染的React组件被移除
  • 表单Model更新不会触发 onShow,所以表单项B 和 表单项A 没有被再次渲染。
  • 但是在请求响应的回调函数中,主动渲染了表单项B,所以表单项B 正常渲染了,而表单项A没有被渲染。
  • 所以表单项B 是正常的,而表单项A 渲染之后又消失了。

导致这个问题的原因

表单项A在 onShow 中渲染。而表单项B setModel 之后,触发了onRender,页面模板重新渲染,组件被移除。而没有触发 onShow,表单项A 没有被再次渲染。

关键的问题

  1. Model更新之后的 View 刷新逻辑,Model更新触发onRender,不会触发onShow。
  2. 表单项A 的渲染逻辑

三、解决方案

  1. 在表单项B的请求相应之后,主动重新渲染表单项A
  2. 将表单项B拆分成一个单独的View视图

方案一:比较简单粗暴,没有自动重新渲染,那就主动重新渲染。但是这样存在的问题是,每一次setModel之后都要主动渲染其他组件,组件数量多的情况就会比较麻烦。

方案二:将表单项B拆分成一个单独的View视图。这样表单项B的业务逻辑就会被隔离在对应的View视图中,如果是Model更新触发onRender也只会影响对应的View视图,不会影响到外部的View视图。

对比起来,方案二会更好一点。

四、其他注意点

在Backbone 项目中引入 React 组件容易遇到一些奇怪的问题,有一些注意点可以检查

  1. React 组件的渲染实际
  2. 模板重新渲染,之前引入的组件会被移除
  3. 在挂载React组件之前,要检查挂载的Dom节点是否已经存在