Reactjs Resact svg/png呈现在新URL上闪烁

Reactjs Resact svg/png呈现在新URL上闪烁,reactjs,react-router,Reactjs,React Router,我正在使用最新的create-react-appconfig,在不同路线之间切换时会遇到问题 所有我的SVG都包含在sprite文件中。从逻辑上讲,sprite.svg文件应该在加载第一页时缓存 但是,每次更改路由(使用react router4)都会加载此文件,从而导致闪烁。内容瞬间改变,但图像加载滞后1s。 对于通过jsx中的import包含的png也一样 从控制台中看不到的地方,相同的文件一次又一次地下载 现场演示(即尝试在页眉部分的“定价/关于”页面之间进行更改) 更新: 我包含SVG

我正在使用最新的
create-react-app
config,在不同路线之间切换时会遇到问题

所有我的
SVG
都包含在sprite文件中。从逻辑上讲,sprite.svg文件应该在加载第一页时缓存

但是,每次更改路由(使用
react router
4)都会加载此文件,从而导致闪烁。内容瞬间改变,但图像加载滞后1s。 对于通过
jsx
中的
import
包含的
png
也一样

从控制台中看不到的地方,相同的文件一次又一次地下载

现场演示(即尝试在页眉部分的“定价/关于”页面之间进行更改)

更新:

我包含SVG图像的方式是哑组件

import React,{Component}来自'React';
从“../images/sprite.svg”导入精灵;
导出默认类SvgIcon扩展组件{
render(){
const{name}=this.props;
返回(
)
}
}
PNG图像

<img src={require(`../images/${authorImage}.png`)} srcSet={require(`../images/${authorImage}@2x.png`)  + ' 2x'} alt=""/>

您得到
200
而不是
304
的原因是您有一个服务工作者,它将拦截请求,并从缓存本身为请求提供服务。这本身就是
200
响应。如果禁用服务人员,您将获得
304


如果问题是图像未提前获取,导致页面更改时闪烁,请尝试使用

componentDidMount() {
  const sprite = "../images/sprite.svg";
  const prefetchLink = document.createElement("link");

  prefetchLink.href = sprite;
  prefetchLink.rel = "prefetch";
  prefetchLink.as = "image";
  document.body.appendChild(prefetchLink);
}
这将提示浏览器在后台获取稍后可能需要的资源(空闲时间),并将其存储在浏览器的缓存中。一旦页面加载完毕,它就开始下载额外的资源,如果用户单击预取链接,它将立即加载内容

对于功能版本:

//custom hook to preload image
const usePreload = (url) => {
  const [loaded, setLoaded] = React.useState(false);
  const onLoad = React.useCallback(() => {
    setLoaded(true);
  }, []);
  React.useEffect(() => {
    const prefetchLink = document.createElement('link');
    prefetchLink.href = url;
    prefetchLink.rel = 'prefetch';
    prefetchLink.as = 'image';
    prefetchLink.addEventListener('load', onLoad);
    document.body.appendChild(prefetchLink);
    //clean up
    return () => document.body.removeChild(prefetchLink);
  }, [onLoad, url]);
  return loaded;
};

export default function SvgIcon({ name }) {
  const url = sprite + '#ico-' + name;
  const loaded = usePreload(url);
  return (
    loaded && ( //only render if image is loaded
      <svg className={'ico ico-' + name}>
        <use xlinkHref={url}></use>
      </svg>
    )
  );
}
//用于预加载图像的自定义挂钩
const useproload=(url)=>{
常量[loaded,setLoaded]=React.useState(false);
const onLoad=React.useCallback(()=>{
setLoaded(真);
}, []);
React.useffect(()=>{
const prefetchLink=document.createElement('link');
prefetchLink.href=url;
prefetchLink.rel='prefetch';
prefetchLink.as='image';
prefetchLink.addEventListener('load',onLoad);
document.body.appendChild(预回迁链接);
//清理
return()=>document.body.removeChild(prefetchLink);
},[onLoad,url]);
返回装载;
};
导出默认函数SvgIcon({name}){
const url=sprite+'#ico-'+name;
const-loaded=useproload(url);
返回(
加载&&(//仅在加载图像时渲染
)
);
}

请注意,如果执行服务器端渲染,则不希望在服务器上执行此代码,因为服务器上没有
文档

添加导入这些图像的代码以及如何使用这些代码。
//custom hook to preload image
const usePreload = (url) => {
  const [loaded, setLoaded] = React.useState(false);
  const onLoad = React.useCallback(() => {
    setLoaded(true);
  }, []);
  React.useEffect(() => {
    const prefetchLink = document.createElement('link');
    prefetchLink.href = url;
    prefetchLink.rel = 'prefetch';
    prefetchLink.as = 'image';
    prefetchLink.addEventListener('load', onLoad);
    document.body.appendChild(prefetchLink);
    //clean up
    return () => document.body.removeChild(prefetchLink);
  }, [onLoad, url]);
  return loaded;
};

export default function SvgIcon({ name }) {
  const url = sprite + '#ico-' + name;
  const loaded = usePreload(url);
  return (
    loaded && ( //only render if image is loaded
      <svg className={'ico ico-' + name}>
        <use xlinkHref={url}></use>
      </svg>
    )
  );
}