让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里,但是因为有接口调用,还是不行

相关推荐
庄毕楠14 分钟前
【Chrome】下载chromedriver的地址
前端·chrome
大猫会长14 分钟前
关闭chrome自带的跨域限制,简化本地开发
前端·chrome
excel21 分钟前
JavaScript 中使用 Set 对数组去重并排序的简洁示例
前端
不断努力的根号七1 小时前
qt框架,使用webEngine如何调试前端
开发语言·前端·qt
伍哥的传说3 小时前
React性能优化终极指南:memo、useCallback、useMemo全解析
前端·react.js·性能优化·usecallback·usememo·react.memo·react devtools
2301_781668619 小时前
前端基础 JS Vue3 Ajax
前端
上单带刀不带妹10 小时前
前端安全问题怎么解决
前端·安全
Fly-ping10 小时前
【前端】JavaScript 的事件循环 (Event Loop)
开发语言·前端·javascript
kupeThinkPoem10 小时前
OpenAI最新大模型GPT-4o体验之Code Copilot AI编程大模型
人工智能·ai编程