CJY0208 / react-router-cache-route

Route with cache for react-router V5 like <keep-alive /> in Vue
https://www.npmjs.com/package/react-router-cache-route
MIT License
1.15k stars 111 forks source link

记录启用 multiple 时 href 中有中文的一个 BUG 及解决方案 #150

Open QYunChao opened 2 years ago

QYunChao commented 2 years ago

环境版本:

"react-router": "^5.1.2", "react-router-cache-route": "^1.12.11",

现象:

未开启 multiple 时,一切正常,能够非常好地缓存各个页面; 开启 multiple 后:链接中有中文的页面第一次都无法缓存,需要第二次才能缓存成功 例如: 从 A页面 -> B页面,第一次从 B 返回 A 时,A 会重新加载(第一次,A没有缓存成功) 再次从新加载的 A页面 -> B页面,第二次从 B 返回 A,A 又不需要重新加载(第二次,A缓存成功

核心代码:

import React from 'react';
import styled from 'styled-components';
import { useHistory } from 'react-router-dom';

function A() {
  const history = useHistory();

  // 页面 A -> 页面 B
  function handleClick() {
    const companyName = '中文参数';
    history.push(`/wxclient/bigdata/company?companyName=${companyName}`);
  }

  return <div onClick={handleClick}>页面A</div>;
}

原因分析:

开始我也百思不得其解,后面看官方文档发现 getCachingComponents 可以查看已缓存的页面内容,于是就输出看看

import { useDidCache, useDidRecover, getCachingComponents } from 'react-router-cache-route';

  useDidCache(() => {
    console.log('getCachingComponents', getCachingComponents());
  });

  useDidRecover(() => {
    console.log('getCachingComponents', getCachingComponents());
  });

实际运行时,输出的内容如下: image

经过分析发现: 第一次 A -> B 时,A 其实是被缓存了的,但是缓存中的 Key 是有中文的 第一次 B 返回 A,链接中的中文却是被编码的,所以和缓存中的 Key 不匹配,A 被重新加载

第二次 A -> B 时,A 再次被缓存,但是这次缓存中的 Key 中的中文也是被编码的 第二次 B 返回 A,缓存中已经存在和被编码中文地址对应的 Key,所以 A 没被重新加载

和截图对应如下: image

解决方案:

修改 页面 A -> 页面 B 的跳转方法,主动将链接中的中文编码:

  // 页面 A -> 页面 B
  function handleClick() {
    const companyName = encodeURI('中文参数'); // 将中文编码
    history.push(`/wxclient/bigdata/company?companyName=${companyName}`);
  }

这样第一次从 A -> B 时缓存的 A 页面对应的 Key 就没有中文了,那么从 B 返回也就正常了。

后记:

最后,虽然问题已经解决了,但是还有以下几个疑问: 1.在浏览器中页面跳转过程中是没有看到过中文地址的,所以为啥在缓存页面时会缓存到带有中文的 Key

  1. CacheRoute 组件没有设置 cacheKey 属性,则 getCachingComponents 不会输出已缓存的页面

如果作者大佬有看到,希望能解惑一二,非常感谢[抱拳]

CJY0208 commented 2 years ago

看到了,真细,明天我看看是啥情况

---原始邮件--- 发件人: @.> 发送时间: 2022年7月28日(周四) 晚上9:39 收件人: @.>; 抄送: @.***>; 主题: [CJY0208/react-router-cache-route] 记录一个启用 multiple 时 href 中有中文的一个 BUG 及解决方案 (Issue #150)

环境版本:

"react-router": "^5.1.2", "react-router-cache-route": "^1.12.11",

现象:

未开启 multiple 时,一切正常,能够非常好地缓存各个页面; 开启 multiple 后:链接中有中文的页面第一次都无法缓存,需要第二次才能缓存成功 例如: 从 A页面 -> B页面,第一次从 B 返回 A 时,A 会重新加载(第一次,A没有缓存成功) 再次从新加载的 A页面 -> B页面,第二次从 B 返回 A,A 又不需要重新加载(第二次,A缓存成功)

核心代码: import React from 'react'; import styled from 'styled-components'; import { useHistory } from 'react-router-dom'; function A() { const history = useHistory(); // 页面 A -> 页面 B function handleClick() { const companyName = '中文参数'; history.push(/wxclient/bigdata/company?companyName=${companyName}); } return <div onClick={handleClick}>页面A</div>; }

原因分析:

开始我也百思不得其解,后面看官方文档发现 getCachingComponents 可以查看已缓存的页面内容,于是就输出看看 import { useDidCache, useDidRecover, getCachingComponents } from 'react-router-cache-route'; useDidCache(() => { console.log('getCachingComponents', getCachingComponents()); }); useDidRecover(() => { console.log('getCachingComponents', getCachingComponents()); });

实际运行时,输出的内容如下:

经过分析发现: 第一次 A -> B 时,A 其实是被缓存了的,但是缓存中的 Key 是有中文的 第一次 B 返回 A,链接中的中文却是被编码的,所以和缓存中的 Key 不匹配,A 被重新加载

第二次 A -> B 时,A 再次被缓存,但是这次缓存中的 Key 中的中文也是被编码的 第二次 B 返回 A,缓存中已经存在和被编码中文地址对应的 Key,所以 A 没被重新加载

和截图对应如下:

解决方案:

修改 页面 A -> 页面 B 的跳转方法,主动将链接中的中文编码: // 页面 A -> 页面 B function handleClick() { const companyName = encodeURI('中文参数'); // 将中文编码 history.push(/wxclient/bigdata/company?companyName=${companyName}); }

这样第一次从 A -> B 时缓存的 A 页面对应的 Key 就没有中文了,那么从 B 返回也就正常了。

后记:

最后,虽然问题已经解决了,但是还有以下几个疑问: 1.在浏览器中页面跳转过程中是没有看到过中文地址的,所以为啥在缓存页面时会缓存到带有中文的 Key

  1. 组件没有设置 cacheKey 属性,则 getCachingComponents 不会输出已缓存的页面

如果作者大佬有看到,希望能解惑一二,非常感谢[抱拳]

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.***>

QYunChao commented 2 years ago

看到了,真细,明天我看看是啥情况

好的,谢谢大佬