前端踩坑记录(一)

89 阅读3分钟

背景

新加入的项目里,代码里封装了一个这样一个方法,估计是想更优雅的使用三元表达式吧

export function safeSetValueWithBoolean(flag: boolean, value?: any, value1?: any): any {
  return flag ? value : value1;
}

因为我是后加入的,我开始在项目里开发时,项目里已经有很多代码在用这个方法了。我个人的习惯,对于非自建的项目,尽量用人家封装好的东西,尽量保持风格一致,以免带来混乱,毕竟人家一直在用的东西应该没什么问题,

经过

注意:所有代码基于项目代码简化

他们之前组件有这样一段代码

{safeSetValueWithBoolean(
  type==='a',
  <>
    <Row>
      <span>
        数量
      </span>
      <span className="card-num">{data.total}</span>
      
    </Row>
    
  </>,
  null
)}

到我开发时,要添加一种新的类型b,b类型时data传递的一定是数组,为了不修改他们原有代码,以及保持风格统一,我就在后面加上了这段代码

{safeSetValueWithBoolean(
  type==='b',
  <>
    <div>{data.map((item) => <span key={item}>{item} </span>)}</div>
    
  </>,
  null
)}

我将type='b',data=(对应获取到b类型的数据)传递给组件验证,没问题,本来想要不要加个可选链来着(?.map),后来觉得已经保证b类型的data一定是数组了,没必要多此一举,就觉得完工了。

然后就被原开发同事告诉我他使用a类型时报错了。

Uncaught TypeError: Cannot read properties of null (reading 'map')

我实验了一下,果然是这样。一开始还没反应过来,想着a类型type==='b'就是false了,怎么会走map方法,然后才反应过来,这个封装方法,和直接用三元表达式还是不一样的,比如value和value1是表达式的情况下,使用封装方法,方法拿到的是两个表达式的值,而不是两个表达式本身,就是说无论真假两个表达式都是要执行的,这和三元表达式是不一样的

复盘

其实我要是直接用三元表达式不用封装方法,或者用可选链,就不会出问题了,那些知识都清楚,但就是因为个人开发习惯、思虑不周、不细心等,还是让问题出现了

总结

  1. 封装方法是为了更优雅的实现相同效果,效果的等价比优雅更重要,一定要验证好。
  2. 不依赖外部调整保证内部逻辑安全,避免出现改动a部分代码引发b部分报错 码上掘金,(和这次报错无关,是我突然想到如果有其他人动了b类型data获取方法造成某些情况不是数组,就会出现他改的代码不报错,而报错行显示是我的代码,所以哪怕我在外部保证了data是数组,我也应该加上可选链)
  3. 不要迷信项目里其他人一直在用的方法,要看看是否适用自己的情况

演示:前端踩坑记录(一)