记录一次 react的竞态 问题

105 阅读1分钟

最近在项目中实现功能时,遇到了一个问题, 由于网络请求后,导致本来修改的值被网络请求后的值覆盖,出现了值变成旧值的问题。

现有的功能是这样的。 有一个表格,表格中展示多行数据, 其中每一行的数据中有最大值和最小值,这两个值可以根据后台返回返回的数据进行Math.max, Math.min计算得出,也可以自己手动进行修改。表格中的网络请求是每隔两秒轮询一次。

本来以为正常开发就可以完成功能。但是自测的时候发现, 有时候我手动更改了最大值后, 网络请求过来的值,总是会覆盖刚才的修改。这个问题不是每次都发生的,有偶发性。后来发现,只要是在网络请求发起后,我进行最大值的修改,这个问题必现。原因是,本地的表格数据修改了,但是网络请求已经发起了,发起的时候,最大值还是用的旧的,所以等发起的这个网络返回值时,就已经覆盖了刚才修改的值。

解决:

  // 设定一个当前的dataSource的版本标记
  const dataSourceVersionRef = useRef(0); // 添加 dataSource 版本标记
  
   // 监听 dataSource 变化,每次更新dataSourceVersionRef
  useEffect(() => {
    dataSourceVersionRef.current++; // 每次 dataSource 变化时增加版本号
    dataSourceRef.current = dataSource;
    startTimer();
  }, [ dataSource ]);
  
  // 在请求前, 获取当前请求的版本标记
   const currentVersion = dataSourceVersionRef.current;
   
   // 请求成功后,把当前的与请求前的进行比较,如果一致就更改,不一致就return
   if (action === undefined &&  currentVersion !== dataSourceVersionRef.current) {
      console.log('DataSource has changed, skipping update');
      return;
   }