duuliy

react的项目遇到的bug

2019-12-19

1.不在from表单中onchange事件不得获取e.target.value.
先调用e.persist() 才能用。。。具体原因不明,可能是在antd中这这个event需要初始化。。。
react特有!如果你想异步访问事件属性,你需在事件上调用 event.persist(),此方法会从池中移除合成事件,允许用户代码保留对事件的引用。

2.键盘事件 .
onKeyDown :
enter:e.keyCode=13

3.antd多个表单提交时。
每个表单都使用Form.create()包裹一下,并且每个表单使用单独的state。

4.yield 才能用call async不能

await 会自动包一层primise,但是call是react-saga里面的方法,用做处理异步。。这两个方式中一些地方重复了,返回的事call对象
但是可以通过const yy=await api.xx()获取值,此时通过dispatch()可以调用reducer,因为put和call都是saga配合yield使用的。

5.如何实现vue中的watch以及computed
https://react.docschina.org/docs/react-component.html#static-getderivedstatefrom

6.proTypes是否还要验证reduer(dva)里面传过来的数据

7.antd 表单如何外面改变里面input的值:
点击保存之后,对表单进行了验证,导致之后请求的数据无法在更新到input框中,也就是说即使在state中有值,也不会更新initialValue值,就导致搜索后的值不能正确填入input中,表单也就提交不了。
this.props.form.setFieldsValue({name:result.data}); 动态设置。。
还有一个问题,如果输入了账号进行搜索后匹配了name,也填入了input框中。但是又修改了账号,然后直接提交,就会导致账号和name不匹配,也就是name是存在的,但就不是对应的账号了。会导致保存之后,如果正确的账号和name已经存在,数据库出现数据存储问题。
给账号输入的Input框添加onChange事件

change = (event) => {
  this.props.form.setFieldsValue({name:''});
}

在表单里面添加onChange拿不到event.target,要getFieldValue获取数据就可以了。
//这样使用validateFields方法不会空数据时调用validator而使他成为异步。

{ required: true, message: '请输入!', validator: (rule, value, callback)=> this.changeSelectedRowsCustom(rule, value, callback, i) }

这样使用就是异步很痛苦!!!!!!!!!!!!!!!!
3.x的版本只能通过父组件传form以及item到子组件(或者父调子的this),然后统一调用validator

{ required: true, message: '请输入!' }
{validator: (rule, value, callback)=> this.changeSelectedRowsCustom(rule, value, callback, i)}

还有种办法是控制value和onChange:

 <Input value=&#123;this.props.value&#125; onChange=&#123;(e)=>this.onChange(e.target.value)&#125; />
onChange=(e)=>this.props.onChange(e)

在form.Item里面还可以用initialValue设置默认值。。
关于setFieldsValue和defaultVal的神奇:
https://blog.csdn.net/qq_31307253/article/details/56482754

8.antd,表格需要选中状态但是不要单选框:
https://www.jianshu.com/p/6d0f5d2a1f4e

9.表单 输入框长度(官网没有,百度不好搜);

 labelCol= &#123;&#123;style:&#123;width: 200&#125;&#125;&#125; 

10.antd 时间选择器
默认值:不能直接用yyxx-gg-zz的形式,只能用moment()来写一个对象的形式的原始时间。

11.antd table尾部统计问题
在footer里面再加一个table
https://codepen.io/afc163/pen/OgExEW?editors=0110
若不想要model的尾部则:footer={null}

12.父调子方法:
函数式组件不能用static 和ref ….父子交互这样的话,只能用互相传props,还是很麻烦。。
用了类组件 用static 方法里面没法调用当前的子this,做model还是不方便。。。
交互多的,我最后还是选了类组件+传统事件向上传this的方法 this.child来用,在compontDidMouint调用父组件方法传this,然后调用子组件的方法。。。!!!!
wrappedComponentRef ref都行

13.组件绑定的值改变,defalutvalue不改变。
defalutvalue始终只会渲染一次,无论怎么改变。。所以动态初始值不能使用默认值,,,只能绑定成value…

14.弹框拖拽效果插件:
https://www.npmjs.com/package/react-drag

15.关于一些原生js的使用方法:
在vue里面是可以直接 location.href ,
但是react不行,只能: window.location.href 。
react 是在类class下面的,而vue是在一大的this。。。。

16.DocumentTitle react 插件,来动态改变页面的title.

17.umi 国际化
https://pro.ant.design/docs/i18n-cn。。

18.antd响应式:
ContainerQuery

19.一个关键单bug: 子组件获取不到router的history.
可以用static 静态化来传router 关键字:contexTypes..
https://blog.csdn.net/sanstu/article/details/80080002

20.antd table thead tbody 不换行+省略号 会超过屏幕计算。

使用 “fixed” 布局方式时,整个表格可以在其首行被下载后就被解析和渲染。这样对于 “automatic” 自动布局方式来说可以加速渲染,但是其后的单元格内容并不会自适应当前列宽。任何一个包含溢出内容的单元格可以使用 overflow 属性控制是否允许内容溢出。
此关键字表示背景相对于视口固定。即使一个元素拥有滚动机制,背景也不会随着元素的内容滚动。

table&#123;
      width: inherit;
      table-layout: fixed;   //这条属性就是让table的内部布局固定大小
      th&#123;
        width: auto;
        div&#123;
          white-space:nowrap ;
          overflow:hidden;
        &#125;
      &#125;
      td&#123;
        overflow:hidden;
        text-overflow:ellipsis;
        white-space:nowrap 
      &#125;
    &#125;

21.state里面的数据 只能setState操作,但是里面的子项可以直接赋值。。

eg: g={
a:1
}
g.a=6….能够正确渲染出来。。

22./asset/relation/list/:page
共享页面的动态路由。!!!

23.多个effects可以用同一个save。

 // 获取基准项信息列表
    * getBenchmarkList (&#123; payload &#125;, &#123; call, put &#125;) &#123;
      const data = yield call(asset.getBenchmarkList, payload)
      yield put(&#123; type: 'save', payload: &#123;好m, benchmarkList: data.body &#125; &#125;)
    &#125;,
    // 获取资产关联的基准项信息列表
    * getAssetBenchmarkList (&#123; payload &#125;, &#123; call, put &#125;) &#123;
      const data = yield call(asset.getAssetBenchmarkList, payload)
      yield put(&#123; type: 'save', payload: &#123; benchmarkList: data.body &#125; &#125;)
    &#125;

  &#125;,
  reducers: &#123;
    save (state, action) &#123;
      return &#123; ...state, ...action.payload &#125;
    &#125;
  &#125;

24.Model组件:
必须加destroyOnClose属性,否则model不会销毁。

25.const { history: { location: { search } } } = this.props
const { assetId, isView } = queryString.parse(search.slice(1))
获取url后面跟的参数,好用

26.表单项的initialValue属性,发现Select组件的placeholder属性并没有起作用:
做判断:
initialValue: publicAccount.certType ? publicAccount.certType : undefined,

27.form里onchange 里面设置setFieldsValue 没有效果
http://ju.outofmemory.cn/entry/348216
normalize 来控制代替setFieldsValue

28.antd 表单动态验证出错:
用动态:
this.props.form.validateFields({ force: true }, (err, values) => {

29.import shortid from “shortid”;
使用下标作为key,只有输入的内容是动态的(动态部分出错排序时)才会出错!!!
唯一id:shortid.generate() 循环时用。
三种情况可以用index作为key。
列表和子元素是静态的
列表中的子元素没有ID,列表永远不会被重新排序或过滤
列表是不可变的

30.
keyDown 会在你按下任何按键时触发,但是 keyPress 只会在你按下的按键可以产生出一个字符的时候触发,白话一点就是你按下这按键是在打字。

31.无法满足的table无限滚动(类似轮播)效果
做table无限滚动(类似轮播),需求是后端每2s推10条数据,要求100时新数据加入10,老数据删除10,同时页面像中奖一样向下滚动。
此页面table 10条数据390px ,用scrollFn 函数 理论达到效果需要2000/390=5.12ms一次,但是浏览器规定延时器最小时间是10ms,实际上加上异步接口渲染等,这里需要28ms。。

const scrollFn = ()=>&#123;
      div.scrollTop++
    &#125;

32.umi.js的404在路由里面输入url错误自动匹配404
{
// path: ‘/404’,
component:’404’,
},

33.不要把所有数据都存redux,如果接口速度慢的话,会有bug
如果不是公共数据,不要用redux,
所有数据都存redux,在很多情况都会存在奇葩bug,比如多开页面并且单点登录,就可能发生内存泄漏。
单点登录下,多开窗口dispatch可能会调不起effectgetBugRepair

34.Upload 多个时,必须加fileList
由于目前antd修复此问题,但是不能切换另一个upload(此时的if判断渲染),不然依然diff定位不到。。
特别是循环的时候。单独2个切换可以定位。

35.Tooltip 会随着屏幕移动,是因为:
拿到当前 的 位置信息 , 动态赋给 当前 div, 最后 绑定一个 resize 事件, 解决 窗口改变之后 位置不对的问题。
antd 可以设置为 绝对定位在 父元素,但是父元素 有 overflow:hidden 之类的属性 tooltip 可能会被截取一部份。

36.ie上面antd table 的columns 增加或减少行,出现留白。
是因为设置了table-layout 把去掉或者:
为表格设置合并边框模型:

table
  &#123;
  border-collapse:collapse;
  &#125;

37.antd 以及组件最好返回undefined不要去返回null,为空很可能报错。

38.Forced reflow while executing JavaScript took ms 强制回流。
减少不必要的DOM深度。DOM树中某一级别的更改会导致该树的每个级别的更改-一直到根,一直到修改节点的子级。这导致花费更多的时间执行回流。
最小化CSS规则,并删除未使用的CSS规则。
如果您进行复杂的渲染更改(例如动画),请不要进行此操作。使用绝对位置或固定位置来完成此操作。
避免使用不必要的复杂CSS选择器-特别是后代选择器-这些选择器需要更多的CPU能力来进行选择器匹配。

39.antd的getFieldDecorator会向自定义组件隐式传入onChange事件以及value值,可以通过这个事件去获得值。setFieldsValue这自定义组件上设置value ={this.props.value}。

40.antd Upload 设置setFieldsValue 的时候必须把他config上的fileList也要设置this.setState({ fileList: file.fileList }),否则不会回显成功。

41.DatePicker 想限制前后时间,中间必须用 || 而不能用 &&
serviceLife < momentDate || momentDate < buyDate

42.atePicker 设置mode为month,则使用disableDate和disableTime不生效。
需要自己包2个monthPicker来解决禁用时间的问题,在3.X版本,若是4.X则有人提pr封装好了。