项目构建
先搞一个react+ts的模版,再上craco换掉原来的脚本,用脚本再去配置less、按需加载
踩坑集合
包管理依赖问题
按照antd官网的“在typescript中使用”进行自定义配置,但是却报了这个错误,暂时看不太懂是什么,记录一下。
临时解决方案:按“在create-react-app中使用”进行自定义配置,就可以了。
在react+ts项目中使用craco配置less不生效的问题
在npm官网找到了解决方案,原来是因为在ts中配置需要写一份文件。附一下 craco-less 的官方说明文档
push代码时说两个仓库不是同一个,得先pull一下代码
pull了又说我不能merge,说是历史记录不一样
只好加参数,允许它不同的历史记录
然后在vsc里手动合并了所有的冲突,再重新add commit push 一条龙
使用redux时状态管理库的类型问题
现象:使用redux
,从状态管理库取出数据时,指定类型是number
,如下图;但是说类型冲突,如下下图
临时解决方法:将取出的数据指定为any
进一步的分析,是connect里传state有问题,应该是state.fieldOption
但是新的问题是,它说state上没有这个属性,却又能console.log出来,查了一下 解决React中使用typescript报错,类型“DefaultRootState“上不存在属性“xxx“以及dispatch类型报错
三种方案解决(前两种是博主的,第三种是我新发现的)
- 一、使用store.getState而不是直接用 state,如上上图所示,即可读到属性了。
- 二、typeof拿到类型,暴露出来,再拿去定义state
第三种:既然它不知道state上有什么东西,那我们就手动给它指定一下就好了。
点击Tab组件切换选项,组件疯狂调用
关于 redux
对于tabTech组件,没有把action上的函数通过connect传到组件身上,而是直接引入直接用,结果发生了一个神奇的现象:发出的action会同时发给所有的reducer,又无法存到状态管理库里面。暂时不太理解这是为什么。
改完就好了,目前看来是redux内部做的处理,要把action函数绑定到对应的组件身上才能发送到对应的reducer。但是组件和对应的reducer是怎么联系起来的呢?经过探究,我发现它并没有去做这种联系,而是单纯的依靠那个combineReducer函数把所有reducer混合在一起,之后当有action的时候,暴力混在一起匹配。细想这是有道理的,这使得所有的组件都能依靠action任意地去修改整个状态管理库
如图,两个reducer都有反应
但是两个reducer又能正确输出各自的prestate
React中将后端返回的html字符串转为dom节点
利用react自带的属性,类似于vue中的v-html,即可。
<div dangerouslySetInnerHTML={{__html: article.article_content}} />
为什么 ViewArticle 组件被render了三次???
无限滚动
获取scrollTop时,ts提示 “srcElement”已弃用
但是能用,暂时就没管它,先做出功能再说。
addEventListener 会因参数的不同添加很多个事件监听
使得获取新数据时,是用之前的选项去拿数据,导致结果混乱。
于是我们每次都挂载并且移除这个事件监听,也是到了这次我才知道了,原来addEventListener如果传了匿名函数,就没办法取消了,所以得用一个const把它写下来,之后才能取消。
接着又发现了新问题,传进去的函数f需要在先前的list的基础上继续请求新数据,但是list一直不更新,处于最初的状态,搞了一整天才明白,原来每次渲染时,所面对的props和state都是不同的
React 之触底加载 在这篇文章中才明白了这件事
浅谈 useRef 在这篇中才更清楚的认识到了,每一次重新渲染的东西都不一样,而正是因为这样,使得我写在一开始的那个addEventListener传进去的那个参数所使用的list是旧的、还没有更新过的list数组。那怎么解决?一开始我想着那就取消之前的事件监听就好了,结果搞了很久发现不行,对react的原理不懂,无法掌控它,一言难尽......最终的解决办法是换条路,既然list是旧的,那就找个不是旧的,所以就用到了useRef,useRef在全局中是唯一的,每次渲染它还是它自己,所以真正的list就记在它身上,而list只是负责拿数据渲染而已。
项目打包运行原地刷新报404
把BrowserRouter换成HashRouter就可以了,但感觉不是一个很好的解决方案。