思路/思维/Good Idea
1. 烟花效果消失太过唐突? 使用透明度opacity加过渡效果
2. 抽屉固定问题
3. Introjs 滚动条问题
4. lastName API 查询很快, fullName查询很慢,可以通过lastName模糊匹配,然后在里面进行全名匹配
5. storybook不能直接用react-pdf 但是可以用底层库pdfjs-dist,可以根据这个库来做PDF预览组件
6. 背景: 点击清除按钮时不要发送请求,单元测试时发现 jest.advanceTimersByTime(300); 没有跳过定时器,上面的方法没跳过定时器,下面的方法跳过了定时器
Component
const debounceSave = useCallback( lodash.debounce(value => fetchOptions(value), 300), [] ); const debounceSave = useCallback( value => setTimeout(() => fetchOptions(value), 300), [fetchOptions] );
Test file
it('should not fetch options after the clear button clicked', async () => { const getOptions = jest.fn(); const props = { options: getOptions, value: initialValue, preventGetOptionsWhenEmpty: true, }; const wrapper = mount(<Typeahead.Async {...props} />); const inputClear = findInputClear(wrapper); inputClear.simulate('click'); expect(getOptions).toHaveBeenCalledTimes(0); });
思路: 正常情况下我们使用setTimeout可以直接跳过的,但是这里失败了。 搜索 lodash debounce unit test,查看stack overflow和源码,发现是因为jest.useFakeTimers()方法只会快进
setTimeout和setInterval,而debounce
用了setTimeout
和 Date,所以我们需要去在Test中修改lodash.debounce的实现
jest.mock('lodash.debounce', () => jest.fn(fn => { fn.cancel = jest.fn(); return fn; }) ); or jest.mock('lodash.debounce', () => fn => { fn.cancel = jest.fn(); return fn; });
7.查找性能问题
通过Chrome浏览器Recorder + console.time + performance API
要考虑是否线上环境数据量巨大导致的,例如lodash.set(obj, [1, 99999999], {}) 会创建100000000个数组 导致页面卡顿, 改为lodash.setWith(obj, [1, 999999999], {}, Object) 即可
8.查找数据问题
思路: 通过redux 查看历史action/state数据,查看数据变化
9. 排查性能bug, 考虑到生产环境的数据量, 所以需要打印item id 和有数据量的长度(脱敏)
dispatch(createAction(abc)
看到这行代码, 不要因为涉及到了redux就想当然的觉得不是这里的问题, 要点进abc看看做了什么, 点进后发现使用了了lodash.set方法(其中的第二个参数写法有问题[number, number])其中第二个number很大, 达到了8亿多, 从而导致了一直在遍历, 页面卡死的问题出现 使用Chrome的redux插件, 可以直观的看到数据结构有问题
1 2 | import { createReducer, original } from '@reduxjs/toolkit' ; original(state.xxx) 可以查看redux的值 |
10.登录后通过中转站跳转到H页面
登录页为jsp
中转站页面为java
H页面为js
没有传fromLoginPage时正常跳转,传了fromLoginPage时跳转到H页面
在点击logo icon时跳转到index?clickLogoIcon=true, 登录时
中转站的java代码 可以通过url来拿clickLogoIcon的值 (boolean clickLogoIcon = request.getParameter("clickLogoIcon") != null)意思就是 只有当前几icon时才不会进入中转站的判断,其他时候都会进入
11. 左侧柱状图,右侧详情
点击左侧柱状图 展开右侧详情, 不一定要获取左侧柱状图的[左右边界坐标, 和当前点击位置坐标], 就算获取了你也不知道你到底点的是柱状图中的那一个分类
可以换种思路, 我只需要知道当前点击的位置是属于哪个分类就行了,这个可以通过第三方库提供的方法拿到
数据少,验证滚动定位功能是否做好,不一定要从上往下,可以从下往上! 先把详情列表滚动到最下面,然后点击左侧第一条数据,看右侧列表是否滚动到上面来
多层级的产品把id组合起来,不要分两个变量,没有i意义,要组合在一起才是一个单独的产品
12. 背景 实现列表滚动加载功能
解决方法: 每次请求数据时保存下搜索值,然后组件中用最新的搜索值和请求数据时保存的搜索值进行对比,只有相同时,才会更新初始值的数据
13. 多考虑把生命周期做成use钩子函数,可以节省很多代码
14. 一个promise请求和多个promise请求 promise.all也可以放在同一个钩子函数中,我们只需要在then中拿到返回的数据即可,多个promise请求放在外面处理。
15. b组件中用了a函数,那么a函数中的catch,也需要在b组件中的catch里面捕获
16. 所有的函数都有操作空间,可以利用里面的参数进行一些操作。
const LIST_ITEM_HEIGHT = 30; <VariableSizeList itemSIze={() => LIST_ITEM_HEIGHT} > {Item] </VariableSizeList>
我们可以打印下itemSize方法的参数
发现有一个index
那么就可以改为
itemSIze={(index) => { if(conditional) { return LIST_REQUEST_FAILED_ITEM_HEIGHT; } else { return LIST_ITEM_HEIGHT; } }}
17. 在一个公共组件/Hooks里面写公共API请求 ?
思路是: 我们只管拿结果,至于请求那个接口,请求参数是什么、如何处理数据,都由外部传进来
const {
// 通过hooks拿到需要的状态 status, data, handleInfiniteData, // 返回处理过的请求API方法,用来替换之前传入的api lastSearchValue, // 最新搜索值 } = useRepeatQuery({
// 传入接口, api,
// 传入处理数据的函数 handleRepeatData, });
// 传入接口,
18. 发现有prop但是组件没有传? 看看是不是connect 或者高阶组件传递的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现