让Cursor都懵圈的React响应式设计

前阵子面试被问到Github好久没更新了,有些惭愧,因为上面都是我自己日常工作生活使用的,确实也没啥需求。

不过最近觉得足球应用可以做一些优化,正好开了144块Cursor会员,也在B站看了些使用教程,就在昨天开动了。

我的需求是这样的,拉取最近完成的比赛信息,展示、日期、场次,然后胜、平、负、让球胜平负、半全场、比分、总进球的赔率

但是A接口只能返回部分信息,让球胜平负、半全程、比分、总进球的赔率要调用B接口才能拿到

除了模态框架子的搭建我是用了之前写好的"代码片段"生成的,后面的都是跟Cursor说,让他搞,感受到了辅助开发的乐趣,一定程度上实现了异步。

有一次在修改后端node.js脚本时,因为请求接口被腾讯云拦截,我让他处理。他加了些代码,后面我让他去掉,结果他只去掉了前面的代码,没管后面的括号这些,导致文件格式有问题,我让他解决,他竟然删除了这个文件,又自以为是的进行了优化,格式是没问题了,好多功能直接无法使用。

旧代码和新写好的代码混在一起,还好Cursor能回退

然后就是翻页问题,因为翻页涉及到调用详情接口,拿到数据后在更新已有的列表数据。

我就反馈切换页面又问题,让他解决,好几次都不行,甚至有一次他自己加了调试代码,让我把控制台输出发给他,也不行,后面都扯到给表格加key强制更新上去了。

而且越来越差,最后变成加载数据后直接空白....

我一看越来越离谱,还是我自己来吧,发现核心问题在还是和React的响应式设计有关

我大概模拟一下,一开始数据结构是这样的

ini 复制代码
  const loadData = async () => {
    const response = await SFootball.getRecentMatches({ startDate, endDate });
    if (response.success) {
      setLoading(false);
      setState({
        list: response.data.list,
      }));

      // 获取第一页的详细赔率信息
      await loadCurrentPageOdds(1, 10);
    } else {
      setLoading(false);
    }
  };
 const loadCurrentPageOdds = async (currentPage: number, pageSize: number) => {
    // 获取当前页所有比赛的matchId
    const matchIds = state.list
      .slice(startIndex, endIndex)
      .map((match) => match.matchId);

    try {
      const oddsResponse = await SFootball.getMatchOddsDetail(matchIds);
      if (oddsResponse.success) {
        // 检查是否为mock数据
        if (oddsResponse.data.isMock) {
          message.warning("详情接口请求被拦截,现在使用的是mock数据");
          setState((prev) => ({ ...prev, isMock: true }));
        }

        // 从响应中提取详细赔率数据(排除isMock字段)
        const { isMock, ...oddsData } = oddsResponse.data;

        // 使用matchId更新数据
        const newData = [...state.list];
        for (let i = startIndex; i < pageSize * currentPage; i++) {
          const match = state.list[i];

          if (oddsData[match.matchId] && state.list[i]) {
            newData[i] = {
              ...match,
              ...oddsData[match.matchId],
            };
          }
        }
        setState(
          produce(prev, (draft) => {
            draft.list = newData;
          })
        )
      }
    } catch (error) {
      console.error("获取详细赔率失败:", error);
    }
  };

问题在于loadCurrentPageOdds中直接取state.list还是空数组,而且setState的时候只更新了list,没有更新page,就会导致翻页无效。

通常解决方案就是通过传参 await loadCurrentPageOdds(response.data.list, 1, 10); 但是翻页也要调用这个函数的

还有就是把list单独提出来, const [list, setList] = useState<NFootball.IFootballMatch[]>([]);

也可以通过传递函数的方式来缓解,但是依旧无法解决形参传递问题

ini 复制代码
setState(pre=>({...pre,...list}))

也可以和produce结合

ini 复制代码
setState(pre=>produce(pre,draf=>{

}))

这种方式我真的太久没有了,可能觉得produce已经完全替代了...

在通过loadData调用loadCurrentPageOdds

javascript 复制代码
setState(pre=>{
  console.log(pre)
  return pre
})

console.log(state.list)

前者打印的是改变后的数据,后者打印一个空数组

那么一道经典的面试题

scss 复制代码
  const [count, setCount] = useState<number>(1);
  <Button
          onClick={() => {
            setCount(count + 1);
            setCount(count + 1);
            setCount(count + 1);
          }}
        >
          点击{count}
        </Button>

问:每次点一次加几,答案:加1 问:如何不改变setCount数量做到每次点一次加3,答案:

javascript 复制代码
           setCount((pre) => pre + 1);
            setCount((pre) => pre + 1);
            setCount((pre) => pre + 1);

但说实话,大部人会有下意识的想到,进阶版面试题可以从上面的例子中演化出来。

比如能不去掉 await loadCurrentPageOdds(response.data.list, 1, 10);第一个形参

我试了下,最后只能尝试把所有逻辑都写进setState里,但是因为有接口调用,还是不行

相关推荐
烂不烂问厨房10 分钟前
前端自适应布局之等比例缩放
开发语言·前端·javascript
kong790692819 分钟前
环境搭建-运行前端工程
前端
CodeLinghu23 分钟前
提示词链模式:一种利用LLM大语言模型处理复杂任务的强大范式
前端·人工智能·语言模型
yuhaiqun198931 分钟前
学AI Agent:从React模式到Plan框架,3条路径一次学透
人工智能·经验分享·笔记·react.js·机器学习·ai·aigc
J2虾虾32 分钟前
关于Ant Design Vue
前端·javascript·vue.js
程序员笨鸟39 分钟前
[特殊字符] React 高频 useEffect 导致页面崩溃的真实案例:从根因排查到彻底优化
前端·javascript·学习·react.js·面试·前端框架
普通网友39 分钟前
框架适配:React/Vue 项目中如何高效使用 debugger 断点
javascript·vue.js·react.js
Shriley_X40 分钟前
React
javascript·react.js·ecmascript
Highcharts.js42 分钟前
从旧版到新版:Highcharts for React 迁移全攻略 + 开发者必知的 5 大坑
前端·react.js·前端框架·编辑器·highcharts
独角鲸网络安全实验室42 分钟前
高危预警!React核心组件曝CVSS 9.8漏洞,数百万开发者面临远程代码执行风险
运维·前端·react.js·网络安全·企业安全·漏洞·cve-2025-11953