乐趣区

关于感悟:功夫在平时

前言

事件源于一次跟 CTO 的交换,过后因为缓和而且间隔解决这些 bug 的工夫过得较长,所以过后答的一塌糊涂,所以就想着从新梳理下过后答复的问题,讲清楚问题的原由,做到功夫在平时,同时加深记忆。

总共说了两件事儿:

1. 翻页问题的异样。2. SSR 与 CSR 界线的辨别。

总的起因

产生这些问题有一个大的前提是因为,我的项目中了用到了服务端渲染(SSR),那么就须要去辨别 SSR 渲染与 CSR 渲染的状况。也因为之前没有解决过 SSR 的我的项目,所以在后期一些组件跟业务解决思维还是 CSR 的模式,导致了一系列的问题。

分页问题的异样

  • BUG 形容

    我的项目曾经上线了很长一段时间了,忽然有用户反馈,浏览器回退按钮回退页面的时候路由曾经回退胜利,然而页面数据还是放弃的以后的数据。

  • BUG 剖析

    分页组件时对立封装的,那就去看看咋回事儿吧! 先看代码

    const clickPage = (page) => {if (callBack && typeof callBack === 'function') {
        // 这个办法是去请求分页的数据
        callBack(page);
      }
    
      if (pathName.includes('?')) {history.push(`${pathName}&page=${page}`);
      } else {history.push(`${pathName}?page=${page}`);
      }
     };
    
    <Pagination.Item
    href={href}
    onClick={(e) => {e.preventDefault();
      clickPage();}}
    >
    页码
    </Pagination.Item>

    下面给出一个页码的例子,Pagination.Item 会被渲染成 a 标签,所以从这里就能确定产生这个问题的起因了,咱们先去拿了以后点击页面的数据,而后再去跳转了页面。

过后看到这就懵逼了,怎么会有这么奇葩的操作呢?分页不是应该先跳转页面,而后在页面内去监听页面的变动,在去申请数据这个流程么?为啥子要这样解决呢?

这就要回到后面所说的大起因了,SSR 跟 CSR 加载场景须要辨别,为什么要去辨别?因为如果所有的模式都去走 SSR 的话,服务端的压力会很大,所以一些用户的点击操作比方翻页、排序等,这些操作就能够采纳 CSR 的模式,所以过后在写一些公共组件(分页,排序)时,就采纳了这种写法:

  1. 分页下面保留地址,有利于搜索引擎的收录跟 SEO,而后实际上采纳客户端跳转形式去扭转路由在跳转前去拿数据。
  2. 这样能保障必定是 CSR 的形式渲染,不必去辨别 SSR 的影响。
    所以基于下面两种起因,采纳了这种形式去实现,其实这套逻辑如果不思考浏览器回退(低频操作)的形式,是齐全可能应用的,这也是一开始为什么没有发现这个 bug 的起因。
  • BUG 解决

    既然 BUG 是由下面那两种‘长处’造成的, 那就隔靴搔痒吧。

    1. 须要去监听路由的变动再去依据对应得参数获取数据。
    2. 保障 SSR 跟 CSR 互不影响,不然服务端渲染过了客户端在执行一遍,太浪费资源了,加载成果也会受影响。
      依照这个思路去批改,首先去掉所有传入的回调函数,让组件只是实现路由的跳转,这样整顿下来竟然发现了一个益处,防止了回调函数的层层传入,居然去除了大量冗余的代码,惟一须要调整并且须要思考的就是如何辨别 SSR 跟 CSR 就能够了 (具体的前面再聊)。
// 调整后的代码  大抵

// 组件
const clickPage = (page) => {if (pathName.includes('?')) {history.push(`${pathName}&page=${page}`);
    } else {history.push(`${pathName}?page=${page}`);
    }
 };

<Pagination.Item
  href={href}
  onClick={(e) => {e.preventDefault();
    clickPage();}}
  >
  页码
</Pagination.Item>

// 页面内
useEffect(()=> {
// 次数省略了辨别服务端跟客户端渲染的条件
 loadDataByPage(page)
}, [page])

SSR 与 CSR 界线的辨别

这个问题是因为下面的革新所带来的思考,怎么辨别这个条件?辨别了怎么样才是最好的形式?其实到当初我感觉也只是做到了去如何辨别条件,有没有更好的形式临时还没有正确的思路。

  • 过后的思考

    1. 减少一个标识,SSR 跟 CSR 的时候别离去扭转这个标识。
    2. 利用现有的数据条件去做辨别,只须要保留数据的时候将路由参数保留即可。

对于第一种办法,长处可能严格辨别进去两种状况,然而须要减少额定字段。而且标识须要频繁更改,并且每个页面都须要减少,即便放到公共数据里,每个页面也须要独自援用,工程量比拟大,并且会使代码的可读性变差,并且页面逻辑,参数多的时候,批改的中央也多,容易出问题,在尝试了一些页面后抉择了放弃这种形式。

对于第二种办法,只须要在存储数据的时候,减少路由参数即可,只须要调整存数据的办法,页面内援用以及申请办法都不须要调整,然而触发逻辑须要写谨严一些,否则容易造成反复申请,资源节约。

持续拿分页举例

// 将触发办法放在页面内,可能触发这里的肯定是 CSR, 因为 SSR 申请不在这里触发
// 革新后 Query.page 路由携带的参数 dataPage 页面存储的以后分页数据
useEffect(() => {
  // 解决 pagenation 分页
  // 减少这些条件判断 是为了避免 SSR 模式后 进入浏览器又触发一遍申请
  if (Query.page && dataPage !== Number(Query.page)) {loadDataByPage(Query.page);
  }

  if (dataPage > 1 && !Query?.page) {loadDataByPage(1);
  }
}, [Query.page]);

到这里批改一个浏览器回退页面数据不正确的 Bug 曾经解决掉了, 这些事件的前因后果曾经讲明确了,本人也算是补救了上次没说好的遗憾跟后悔。

可能只看这里的例子你感觉也不是很简单的逻辑,然而这其中一个条件的扭转,对于繁多的列表页的确也只须要批改这么多久够了,然而咱们有一个非常复杂的页面(个人主页),路由组合,外加分页,筛选条件等组合起来有几十种的变动,要解决好这些须要组好认真的辨别,也是相当简单的,而且在解决这些条件时,尽量抉择繁多条件繁多解决,防止同时依赖多个条件,否则会造成额定的影响因素,这些都是一点一点的调试进去的。

结尾

日常多思考和积攒,防止长期抱佛脚,才不会关键时刻卡壳,心里素质有待增强,只是一普普通通的谈话为什么会这么缓和?亡羊补牢,为时未晚,对于本人的有余要做到及时补充,加油打工人!!!

题外话

大多数程序员其实都在解决业务,如何从业务中体现价值?或者说在汇报的时候如何去展现业务中的亮点?当你感觉解决的业务没什么亮点又该怎么取讲?欢送大佬给出倡议跟探讨!

退出移动版