Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么随机(看起来如此)重新加载缓存的图像?_Javascript_Html_Reactjs_Jsx - Fatal编程技术网

Javascript 为什么随机(看起来如此)重新加载缓存的图像?

Javascript 为什么随机(看起来如此)重新加载缓存的图像?,javascript,html,reactjs,jsx,Javascript,Html,Reactjs,Jsx,所以我一直在尝试使用React开发一个简单的网站。目前我想要实现的基本布局是每个页面都有(从上到下):图像、导航栏和内容。我将图像和导航栏放入标题组件中。其思想是,每当用户从导航栏中选择另一个页面时,顶部的图像就会相应于该页面发生变化(页眉接收“banner”属性,该属性指示要切换到的图像文件的名称)。 出于某种原因,当我在页面之间切换时,有时React会决定重新加载图像组件,即使它已被缓存 我担心在切换到相应页面时,每个图像都会被单独加载,因此我明确添加了一些代码,以便立即加载所有图像,并且我

所以我一直在尝试使用React开发一个简单的网站。目前我想要实现的基本布局是每个页面都有(从上到下):图像、导航栏和内容。我将图像和导航栏放入标题组件中。其思想是,每当用户从导航栏中选择另一个页面时,顶部的图像就会相应于该页面发生变化(页眉接收“banner”属性,该属性指示要切换到的图像文件的名称)。 出于某种原因,当我在页面之间切换时,有时React会决定重新加载图像组件,即使它已被缓存

我担心在切换到相应页面时,每个图像都会被单独加载,因此我明确添加了一些代码,以便立即加载所有图像,并且我可以在dev.tools的“网络”选项卡上验证它是否正常工作(当我加载主页面时,网络会检测到对所有图像的请求,并做出200响应)。一旦这样做了,奇怪的事情就开始发生了。每当我切换到另一页时,两件事中的一件会随机发生:

  • 映像会立即切换(如预期的那样),并且不会发出任何网络请求
  • 页面“重新呈现”其组件,就好像它必须重新加载页眉图像一样,也就是说,页面内容看起来是(微小的空白、导航栏、内容),然后返回到(图像、导航栏、内容),这会产生一种丑陋的抖动效果。每当发生这种情况时,dev.tools中的“网络”选项卡都会捕捉到一个请求,该请求包含304响应 现在,304表示请求的资源尚未修改。但如果尚未修改(即缓存),则:

  • 为什么React需要像重新加载资源一样重新绘制它,即使有时它可以立即重新绘制
  • 为什么它不一致地发送获取资源的请求?对于何时检查项目是否缓存以及何时不缓存,是否有一些规则 下面是标题组件的一些代码:

    class Header extends React.Component {
    
        static images_loaded = false;
    
        constructor(props) {
            super();
    
            this.state = {
                banner: props.banner,
                map: {}
            }
    }
    
        componentDidMount() {
            const map = {};
            if (!Header.images_loaded) {   // trying to load once per all Header instances
                ['main_page', 'about_me', 'bits', 'portfolio', 'resume', 'thoughts'].forEach((name) => {
                    const img = new Image();
                    img.src = require('./banners/' + name + '.png');
                });
    
                Header.images_loaded = true;
    
            }
        }
    
        render() {
          return ( 
                <div>
                <img src={require('./banners/' + this.state.banner + '.png')} /> 
                    <div>
                        <Navbar bg="dark" variant="dark" expand="lg" sticky="top">
                           {'Navbar contents'}
                        </Navbar>
                    </div>
                </div>
              );
            }
      }
    
      export default Header;
    
    类头扩展React.Component{
    静态图像_加载=错误;
    建造师(道具){
    超级();
    此.state={
    横幅:道具,横幅,
    映射:{}
    }
    }
    componentDidMount(){
    常量映射={};
    如果(!Header.images_loaded){//尝试为每个头实例加载一次
    [‘主页’、‘关于我’、‘bits’、‘公文包’、‘简历’、‘想法’]。forEach((姓名)=>{
    const img=新图像();
    img.src=require('./横幅/'+name+'.png');
    });
    Header.images\u loaded=true;
    }
    }
    render(){
    报税表(
    {'Navbar contents'}
    );
    }
    }
    导出默认标题;
    
    预期行为: 在页面之间切换会导致图像立即切换,而无需重新加载

    实际行为: 在页面之间切换会导致随机“重新获取”和图像重新呈现

    我是否误解了缓存的工作原理,或者可能会对工作流做出反应?我真的很困惑到底发生了什么以及为什么。 非常感谢别人的帮助,谢谢


    UPD:图像大小在1.45-3.02 Mb范围内变化使用create react app,您可以通过在渲染函数外部导入文件来获得所需的结果。如果映像小于10000字节,它将返回数据uri而不是路径,以减少对服务器的请求数

    如果您使用的是react router之类的工具,您应该能够基于以下路径更改图像src:

    import React from "react";
    import { withRouter } from "react-router";
    import red from "./banners/red.png";
    import blue from "./banners/blue.png";
    import green from "./banners/green.png";
    
    const colorMap = {
      "/": red,
      "/about/": blue,
      "/users/": green
    };
    
    const Header = props => {
      console.log(props, colorMap[props.location.pathname]);
      return (
        <div>
          <img
            alt=""
            src={colorMap[props.location.pathname]}
            style={{ height: "200px", width: "200px" }}
          />
        </div>
      );
    };
    
    export default withRouter(Header);
    
    
    从“React”导入React;
    从“react router”导入{withRouter};
    从“/banners/red.png”导入红色;
    从“/banners/blue.png”导入蓝色;
    从“/banners/green.png”导入绿色;
    常量颜色映射={
    “/”:红色,
    “/about/”:蓝色,
    “/users/”:绿色
    };
    const Header=props=>{
    log(props,colorMap[props.location.pathname]);
    返回(
    );
    };
    使用路由器导出默认值(标题);
    

    对于当前的实现,可以使用
    this.props.banner
    而不是
    this.state.banner
    。将状态指定给道具通常被认为是一种反模式,因为它会复制数据并使真相来源变得混乱。

    使用create react app,您可以通过在渲染函数外部导入文件来获得所需的结果。如果映像小于10000字节,它将返回数据uri而不是路径,以减少对服务器的请求数

    如果您使用的是react router之类的工具,您应该能够基于以下路径更改图像src:

    import React from "react";
    import { withRouter } from "react-router";
    import red from "./banners/red.png";
    import blue from "./banners/blue.png";
    import green from "./banners/green.png";
    
    const colorMap = {
      "/": red,
      "/about/": blue,
      "/users/": green
    };
    
    const Header = props => {
      console.log(props, colorMap[props.location.pathname]);
      return (
        <div>
          <img
            alt=""
            src={colorMap[props.location.pathname]}
            style={{ height: "200px", width: "200px" }}
          />
        </div>
      );
    };
    
    export default withRouter(Header);
    
    
    从“React”导入React;
    从“react router”导入{withRouter};
    从“/banners/red.png”导入红色;
    从“/banners/blue.png”导入蓝色;
    从“/banners/green.png”导入绿色;
    常量颜色映射={
    “/”:红色,
    “/about/”:蓝色,
    “/users/”:绿色
    };
    const Header=props=>{
    log(props,colorMap[props.location.pathname]);
    返回(
    );
    };
    使用路由器导出默认值(标题);
    

    对于当前的实现,可以使用
    this.props.banner
    而不是
    this.state.banner
    。将状态分配给道具通常被认为是一种反模式,因为它会复制数据并使真相的来源变得混乱。

    在codesandbox.io中看到一个示例会很好。你不需要
    !Header.images\u加载的
    图像将由componentDidMount加载一次。您不需要组件中的状态,因为您只需要使用道具。定义“交换页面”的含义…反应路由器页面或完成新页面load@charlietfl是的,我说的页面是指“页面”。我使用Link而不是普通的href在它们之间切换,所以我不认为这是一个反复加载页面的问题。另外,正如我提到的,som