react开发经验
react 开发经验
react 事件函数的最后一个参数没有明确指定时,是 event 对象。
react 里想要在当前页面的地址栏里加参数,我们直接把带有参数的路径 push 即可,当前页面不会刷新,但是地址栏会变。
react 里重新给 img 的 src 赋值 gif 图片地址时,gif 不会重头播放;需要获取 img 的 dom 元素,然后给 dom 元素的 src 属性赋值才行。
umi 里动态配置 TDK,借助 umi 的两个工具——history.listen()来监听路由,根据不同路由来设置不同的 TDK 文案;——使用@umijs/plugin-helmet 插件,设置 TDK 标签。
withRouter 的作用和适用场景:
withRouter 的作用
作用:是将一个组件包裹进
Route里面, 然后react-router的三个对象history, location, match就会被放进这个组件的props属性中.- 默认情况下必须是经过路由匹配渲染的组件才存在 this.props,才拥有路由参数,才能使用编程式导航的写法,执行 this.props.history.push('/ ')跳转到对应路由的页面
然而不是所有组件都直接与路由相连(通过路由跳转到此组件)的,当这些组件需要路由参数时,使用 withRouter 就可以给此组件传入路由参数,此时就可以使用 this.props
- 高阶组件中的
withRouter, 作用是将一个组件包裹进Route里面, 然后react-router的三个对象history, location, match就会被放进这个组件的props属性中.此时这个组件就具备了路由的属性
react 里使用 mixins:https://www.cnblogs.com/wangpenghui522/p/6214953.html 【mixins】
别人的笔记:整理
react 获取 ref 的三种方式:
- https://www.jianshu.com/p/7dc465e46616
- 使用 TS 声明一个 ref:
myInput: React.Ref<HTMLInputElement> = React.createRef();我们可以使用 this.myInput 拿到 input 元素。
- 使用 TS 声明一个 ref:
ant 注意事项:
ant 自己的组件不能接收文档之外的其他属性,否则在控制台报错,所以需要删除文档之外的属性。
message.config 是一个全局配置,如果我们想要给不同的组件配置不同样式,那么我们不能让项目一起来就让 message.config()无条件运行。例如:可以在组件挂载完成的时候执行,配置如下,此时就可以在不同组件写不同的样式:
componentDidMount() { message.config({ // 这是全局配置,如果整个项目message样式统一此时只能在全局的地方去配置,否则项目一起来就跑这一段代码,会导致其他组件使用到message组件的时候如果没有配置getContainer选项就会报错。 top: 150, duration: 3, maxCount: 1, getContainer: () => document.getElementById("setmateria") as HTMLElement, // 把元素挂载在id为setmateria元素下,来保证当前组件的样式和其他组件的样message式不一样 // prefixCls: "znjj-message", }); }1
2
3
4
5
6
7
8
9ant 中:Prompt 组件的使用,这是 react-router 提供的功能
- 离开页面的方式不能是 a 链接,否则不会触发 Prompt 组件执行。
<Prompt
when={this.state.isPrompt} // when为true时,此组件渲染
message={(location, action) => {
!location.pathname.startsWith("/videoEdit") && // 离开‘/videoEdit’页面时自定义弹框内容
Modal.confirm({
icon: <ExclamationCircleOutlined />,
title: this.renderTitle(),
content: "是否保存您所做的所有更改?",
okText: "保存",
cancelText: "不保存",
className: `${style.gobackConfirm}`,
onOk: () => {
// formInstance?.submit();
this.handleSaveProduct(); //调用保存的方法
this.nextStep(location.pathname);
},
onCancel: () => {
this.nextStep(location.pathname);
},
});
return false; // 始终阻止页面直接跳转
}}
/>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
react 调试:
- https://juejin.cn/post/6877546408925200391
css module 怎么和已有的组件库一起使用:
.slider { //假如我们自己在 ant 的 slider 组件上添加一个自己的 slider 类名
&:global(.ant-slider-disabled) { :global{.ant-slider-handle,
.ant-slider-dot {
border-color: #b3b3b3 !important;
background-color: #b3b3b3;
}
}}
}
编译后的结果:
.slider___VsVSs {
color: #333;
}
.slider**VsVSs:hover .ant-slider-track**G6b_q {
background-color: rgba(0, 0, 0, 0.6) !important;
}
.slider___VsVSs.ant-slider-disabled .ant-slider-handle,
.slider___VsVSs.ant-slider-disabled .ant-slider-dot {
border-color: #b3b3b3 !important;
background-color: #b3b3b3;
}
react 的属性和值可以被子组件继承:我们只需要在子组件上写 {...props}就可以继承父组件的属性和对应的值。
react 的属性可以传递任何值:包括一个组件
topLeft={
} topRight={
} bottom={}
topLeftWidth={400}
resize={() => {}}
>
jsx/tsx 里组件可以直接视为变量:
- 声明变量:const someCmp =
- 使用变量:{
}。我们把 render 函数里{}里的内容视为 js。
- 声明变量:const someCmp =
防止组件重复渲染:
防止子组件重复渲染:同时满足 2 个条件
子组件引用不变:https://overreacted.io/before-you-memo/
子组件属性对比时值无变化
- 基本数据类型:值相等
- 复杂数据类型(引用数据类型): 地址相等
# 为什么在 React 的 Render 中使用箭头函数和 bind 会造成重新渲染的问题 :
- https://blog.csdn.net/luo1055120207/article/details/79025365
- 解决办法,参考:https://juejin.cn/post/6844903747282452488 第 3 种方式。
# useCallback 状态不更新的原因以及解决方法 :
https://blog.csdn.net/adadsadadda/article/details/116334636
React Hooks 踩坑分享:https://cloud.tencent.com/developer/article/1684307?from=15425&areaSource=102001.1&traceId=A_9U7j-K14juO6GSPFz8b
- fc 组件中,事件处理函数执行时所对应的数据,即使在后面又更新了,但是函数里对应的数据并不会够更新(函数里的数据会对应函数开始执行那一时刻的值,在执行过程中不会被改变)。所以处理事件函数时,一旦被 useeCallBack 包裹那么里面的值就一定会存在闭包(因为函数在依赖改变时会被更新对应新的函数不再是以前的函数)。如果函数里想获取最新值,那么我们直接可以通过 ref 去解决。
- 函数在执行时,才会去取那一时刻变量所对应的值
- 方法里使用了一个对象,那么在方法运行时才会去读取对象以及对象对应的属性。
# React Hooks 使用的 5 大误区,看看你中了几个
- https://mp.weixin.qq.com/s/TGJBVs4wDtwcO9hOFUrMuw
# React 函数式组件中实现「批量更新」的两种方式
- 参考:https://zhuanlan.zhihu.com/p/426028762
- import { unstable_batchedUpdates as batchedUpdates } from 'react-dom'
- 参考:https://www.jianshu.com/p/f0e1b84e3883
- 把多个状态合并到一个状态里去
# React 性能优化指南之性能分析与 16 种优化方法大总结
- 性能分析以及优化方法总结:https://mp.weixin.qq.com/s/_SafpFkho1omGWdvx6DMvg
- profiler 的使用
- 参考原文:通过 React Profiler,开发者可以查看组件 Render 过程耗时,但无法知晓提交阶段的耗时。尽管 Profiler 面板中有 Committed at 字段,但这个字段是相对于录制开始时间,根本没有意义。所以提醒读者不要通过 Profiler 定位非 Render 过程的性能瓶颈问题。
- 还可以参考:https://juejin.cn/post/7008337341634854942 https://juejin.cn/post/7077091328420478989
- 懒加载、懒渲染
- profiler 的使用
# React 性能优化优化
触发事件时,需要传递数据,此时我们的写法
// 错误写法如下: <div onClick = {()=>fn(data) /> // 好的写法: const handleClick = useCallback((e)=>{ // 对于非常简单的数据我们直接 // const data = e.currentTarget.dataset.xx // 对于assetList类列表数据 xxx 可以是 index const data = assetList[e.currentTarget.dataset.xx as unknown as number] },[]) <div data-xx={xxx} onClick = {handleClick}) />1
2
3
4
5
6
7
8
9
10
对于在大量数据中只需要更新其中几个数据时:
- 我们没必要为了几个数据而更新全部数据。我们只需要让组件产生更新动作,把需要更新的几条数据更新其数据地址即可。
- 第一步:数据上我们只需要更新对应数据的地址(例如大量的列表数据我们可以用ref存,然后找到对应的数据重新赋值(新值必须是新数据地址),显示的时候拿这个ref去map遍历显示即可。)
- 第二部:我们可以随便更新一个其他的简单数据,目的是让组件产生更新作品的行为。例如通过setState切换某个布尔值就可以。
- 我们没必要为了几个数据而更新全部数据。我们只需要让组件产生更新动作,把需要更新的几条数据更新其数据地址即可。
hooh或自定义hook的作用:
- 实现某种逻辑的复用