001
最后更新于:2022-04-02 05:40:01
[TOC]
## 前言
本文主要摘录react项目实践的时候一些典型的问题。
### 滑动时不能阻止默认事件报错
报错:[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive
分析:由于浏览器必须要在执行事件处理函数之后,才能知道有没有掉用过 preventDefault() ,这就导致了浏览器不能及时响应滚动,略有延迟。
所以为了让页面滚动的效果如丝般顺滑,从 chrome56 开始,在 window、document 和 body 上注册的 touchstart 和 touchmove 事件处理函数,会默认为是 passive: true。浏览器忽略 preventDefault() 就可以第一时间滚动了。
举例:
```
window.addEventListener('touchmove', func) 效果和下面一句一样
window.addEventListener('touchmove', func, { passive: true })
```
//导致问题
如果在以上这 3 个元素的 touchstart 和 touchmove 事件处理函数中调用 e.preventDefault() ,会被浏览器忽略掉,并不会阻止默认行为。
解决方案:
1、注册处理函数时,用如下方式,明确声明为不是被动的
window.addEventListener('touchmove', func, { passive: false })
2、应用 CSS 属性 touch-action: none; 这样任何触摸事件都不会产生默认行为,但是 touch 事件照样触发。
更多介绍:[touch-action引起无法滑动的问题](https://juejin.im/post/5bcd8c7051882578247075dd)
### react 设置复杂对象属性在页面前进后退时的问题
场景: setState 如果数据复杂的时候,那么在页面离开组件销毁时,再进入渲染时复杂对象的属性并没有被重置,而简单对象属性有被重置,如果这两者有对应关系,就会导致此时通过页面前进后退导致的销毁组件状态不一致。
解决方案:目前过度阶段的解决方案是在componentWillUnmount 的时候 吧数据全部重置到初始状态解决的。
延伸思考:
类似的问题导致的原因还是对简单和复杂对象的设置和销毁有问题,如何从源头解决才是根本
### 页面前进后退对生命周期以及数据的影响
有关页面前进后退对生命周期以及数据的影响是如何的要做深入的研究,如何利用页面监听做自己想要的数据设置和交互设置。
### 页面栈与生命周期的关联性设计
包括页面栈的使用,跳转到哪些指定页面,而不是历史页面的前进和后退
### redux去真正适合解决哪些问题
redux或者mobox的本质还是用来解决跨组件、跨页面共享数据的,如果某些时候就用redux的方案是否科学合理,因为redux是集中管理,过多的管理里只有一个页面会用而不会分发的数据思考下来总是有点不妥的
### 如何系统的做页面状态的保留,体验的优化
### 页面刷新时 与 页面栈前进后退的区分思考,对生命周期的影响
### 当id变化时 组件不更新的问题
主要是同一个组件用来渲染不同的组件,当id变化时,组件不更新的问题。这个主要解决方案是:在componentWillReceiveProps的生命周期里重新获取数据进行渲染。
其他方案可以是:将detail组件的部分进行封装,用函数组件实现。
### state中的值为复杂类型时,数据没有自动清除
场景:页面为一个调查问卷,每个题目都有选项,并且标注着是否为选中的布尔类型。默认为false 的。当组件销毁的时候,checked并没有全部重置为false,那么就会导致ui与数据不一致的bug
```
this.state = {
questionArr : [{
title:'sf',
options:[{
title:'option 1',
checked:false
}]
}]
}
```
解决方案:在组件要销毁时,代码进行重置
```
componentWillUnmount() {
let { questionArr } = this.state
let questionArrCp = questionArr.map(item => {
item.options && item.options.map((choice, index) =>
choice.checked = false)
return item
})
this.setState({
questionArr:questionArrCp
})
}
```
### 跨域报错
- [github issue链接](https://github.com/CompuIves/codesandbox-client/issues/667)
在使用codesanbox的时候报错,具体报错如下:
```
A cross-origin error was thrown. React doesn't have access to the actual error object in development.
```
解决方案:
';