Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.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_Css_Reactjs - Fatal编程技术网

Javascript 主组件仅在刷新时加载(不在初始加载时),竞态条件?

Javascript 主组件仅在刷新时加载(不在初始加载时),竞态条件?,javascript,html,css,reactjs,Javascript,Html,Css,Reactjs,我遇到的情况是,当第一次加载页面时,应该加载在Home.js中的图像不会加载,直到在浏览器(Chrome)上按下刷新按钮。这种情况发生在开发服务器和实时生产服务器中,有时必须在图像显示之前多次点击刷新 请注意,我对所有web开发都是新手,而且我的大部分经验都是在Android开发中 我认为这与我将图像加载到主组件的方式有关。通过日志记录,我发现图像是在页面加载之前加载的(使用componentDidMount()),因此我正在寻找任何可用的解决方案 谢谢,这是密码 Main.js: import

我遇到的情况是,当第一次加载页面时,应该加载在
Home.js
中的图像不会加载,直到在浏览器(Chrome)上按下刷新按钮。这种情况发生在开发服务器和实时生产服务器中,有时必须在图像显示之前多次点击刷新

请注意,我对所有web开发都是新手,而且我的大部分经验都是在Android开发中

我认为这与我将图像加载到主组件的方式有关。通过日志记录,我发现图像是在页面加载之前加载的(使用
componentDidMount()
),因此我正在寻找任何可用的解决方案

谢谢,这是密码

Main.js:

import React from 'react';
import { withRouter, Route, NavLink, HashRouter } from 'react-router-dom';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faInstagram, faGithub, faFacebook } from '@fortawesome/fontawesome-free-brands';
import 'bootstrap/dist/css/bootstrap.css';
import Favicon from 'react-favicon';

import Home from './Home';
import Contact from './Contact';
import socialMediaLinks from './utilities/Utils';

class Main extends React.Component {
    constructor() {
        super();
        this.state = { 
            screenWidth: null,
            isMobile: false,
        };
        this.handleResize = this.handleResize.bind(this);
    }

    componentDidMount() {
        window.addEventListener('resize', this.handleResize.bind(this));
        this.handleResize();
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.handleResize);
    }

    handleResize() {
        this.setState({ screenWidth: window.innerWidth });
        console.log(`width is ${this.state.screenWidth}`);
    }

    render() {        
        return (
            <HashRouter>
                <div>
                <Favicon url='./favicon.ico' />
                    {/* Navigation */}
                    <nav className='navbar fixed-top bg-dark flex-md-nowrap'>
                            {/* Social Media */}
                            <a className='social-media-link' href={socialMediaLinks['instagram']}><FontAwesomeIcon icon={faInstagram} size='lg' /></a>
                            <a className='social-media-link' href={socialMediaLinks['github']}><FontAwesomeIcon icon={faGithub} size='lg' /></a>
                            <a className='social-media-link' href={socialMediaLinks['facebook']}><FontAwesomeIcon icon={faFacebook} size='lg' /></a>
                            <ul className="header">
                                <li className='nav-option'><NavLink exact to='/'>Home</NavLink></li>
                                <li className='nav-option'><NavLink to='/contact'>About/Contact</NavLink></li>
                            </ul>
                    </nav>
                    {/* Main Page */}
                    <div className='content container-fluid' align='center'>
                        <div className='row'>
                            <Route exact path='/' component={withRouter(Home)} />
                            <Route path='/contact' component={withRouter(Contact)} />
                        </div>
                        <footer>Created by me :)</footer>
                    </div>
                </div>
            </HashRouter>
        );
    }
  }

export default Main;
index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    <link rel='icon' href='../src/favicon.ico' type='image/x-icon' />
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
这导致:

硬重新加载后(ctrl+F5):
images=[undefined,undefined,undefined,undefined,undefined,undefined,undefined]
刷新后(ctrl+R):
images=[{…},{…},{…},{…},{…},{…},{…},{…}]
--所有这些都带有
typeof:Symbol(react.element),键入:“img”

控制台。log
不能保证是同步的,所以执行顺序不能依赖于它。有些引擎是,有些不是

我也不会依赖于
require.context
,尤其是当您使用
createreact应用程序时。见:

一般来说,如果您的项目已经为ES模块设置好,并且您发现自己需要
require
,那么在我看来,这有点像代码味道。ES模块的整个要点是使作用域成为静态的,而不是动态的,这样编译器就可以推断缩小时要丢弃什么。目录结构在运行时实际上不再存在;它全部被缩小成一个大文件,要么由WebpackDev服务器动态运行,要么作为产品构建的一部分

文件是否太多,无法直接导入模块?您可以为
imageList
设置一个单独的模块来处理加载和导出,然后只需
import
并直接在组件中使用即可:

然后,您可以进行一个测试,以确保将来不会遗漏任何测试(注意,测试直接使用文件结构在节点中运行,而不是Web包最终过程):

如果确实有太多的代码,或者它们会经常更改,我通常喜欢在命令行上自动创建代码。下面是quick n dirty,但应接近您所需的,具体取决于路径:

#!/usr/bin/env node

const { readdirSync, writeFileSync } = require('fs')
const { extname, join } = require('path')

const relPath = (...paths) => join(__dirname, ...paths)
const dir = relPath('src', 'images')

const printLoaderFile = () => {
  const imageFiles = readdirSync(dir).filter((file) => {
    return extname(file).match(/\.(png|jpe?g|svg)$/)
  })

  const output = []

  imageFiles.forEach((file, index) => {
    output.push(`import image${index} from '${dir}/${file}'`)
  })

  output.push('\nexport default {')
  imageFiles.forEach((file, index) => {
    output.push(`  '${file}': image${index},`)
  })
  output.push('}\n')

  writeFileSync(relPath('src', 'imagesList.js'), output.join('\n'))
}

printLoaderFile()

console.log
不能保证是同步的,所以执行顺序不能依赖于它。有些引擎是,有些不是

我也不会依赖于
require.context
,尤其是当您使用
createreact应用程序时。见:

一般来说,如果您的项目已经为ES模块设置好,并且您发现自己需要
require
,那么在我看来,这有点像代码味道。ES模块的整个要点是使作用域成为静态的,而不是动态的,这样编译器就可以推断缩小时要丢弃什么。目录结构在运行时实际上不再存在;它全部被缩小成一个大文件,要么由WebpackDev服务器动态运行,要么作为产品构建的一部分

文件是否太多,无法直接导入模块?您可以为
imageList
设置一个单独的模块来处理加载和导出,然后只需
import
并直接在组件中使用即可:

然后,您可以进行一个测试,以确保将来不会遗漏任何测试(注意,测试直接使用文件结构在节点中运行,而不是Web包最终过程):

如果确实有太多的代码,或者它们会经常更改,我通常喜欢在命令行上自动创建代码。下面是quick n dirty,但应接近您所需的,具体取决于路径:

#!/usr/bin/env node

const { readdirSync, writeFileSync } = require('fs')
const { extname, join } = require('path')

const relPath = (...paths) => join(__dirname, ...paths)
const dir = relPath('src', 'images')

const printLoaderFile = () => {
  const imageFiles = readdirSync(dir).filter((file) => {
    return extname(file).match(/\.(png|jpe?g|svg)$/)
  })

  const output = []

  imageFiles.forEach((file, index) => {
    output.push(`import image${index} from '${dir}/${file}'`)
  })

  output.push('\nexport default {')
  imageFiles.forEach((file, index) => {
    output.push(`  '${file}': image${index},`)
  })
  output.push('}\n')

  writeFileSync(relPath('src', 'imagesList.js'), output.join('\n'))
}

printLoaderFile()

通过以下方式修改
Home.js
,可以快速加载图像,而无需刷新:

import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import './index.css';

var imageList = [];

function importAll(r) {
    const keys = r.keys();
    let images = {};
    for (var k in keys) {
        images[keys[k].replace('./', '')] = r(keys[k]);
    }
    return images;
}

const images = importAll(require.context('./images/resized/', false, /\.(png|jpe?g|svg)$/));

for (var image in images) {
    var newImage = new Image(images[image], images[image], null);
    newImage.name = images[image];
    newImage.src = images[image];
    imageList.push(newImage);
}

class Home extends React.Component {
    constructor() {
        super();
        this.state = {
            images: [],
        }
    }

    componentDidMount() {
        this.setState({ images: imageList });
    }

    render() {
        let imagesFinal = [];
        for (var image in this.state.images) {
            console.log(this.state.images[image].src);
            if (this.state.images[image].naturalHeight > this.state.images[image].naturalWidth) {}
            imagesFinal.push(<img src={this.state.images[image].src} className='landscape-img' alt=''></img>);
        }

        return <div>{imagesFinal}</div>;
    }
}

export default Home;
从“React”导入React;
导入'bootstrap/dist/css/bootstrap.css';
导入“./index.css”;
var imageList=[];
函数输入(r){
常量键=r.键();
让图像={};
for(键中的变量k){
图像[keys[k]。替换('./','')=r(keys[k]);
}
返回图像;
}
const images=importAll(require.context(“./images/resized/”,false,/\(png | jpe?g | svg)$/);
用于(图像中的var图像){
var newImage=新图像(图像[Image],图像[Image],空);
newImage.name=图像[图像];
newImage.src=images[image];
imageList.push(newImage);
}
类Home扩展了React.Component{
构造函数(){
超级();
此.state={
图像:[],
}
}
componentDidMount(){
this.setState({images:imageList});
}
render(){
设imagesFinal=[];
for(此.state.images中的var图像){
console.log(this.state.images[image].src);
如果(this.state.images[image].naturalHeight>this.state.images[image].naturalWidth){}
imagesFinal.push();
}
返回{imagesFinal};
}
}
导出默认主页;

通过以下方式修改
Home.js
,导致图像加载速度快且无需刷新:

import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import './index.css';

var imageList = [];

function importAll(r) {
    const keys = r.keys();
    let images = {};
    for (var k in keys) {
        images[keys[k].replace('./', '')] = r(keys[k]);
    }
    return images;
}

const images = importAll(require.context('./images/resized/', false, /\.(png|jpe?g|svg)$/));

for (var image in images) {
    var newImage = new Image(images[image], images[image], null);
    newImage.name = images[image];
    newImage.src = images[image];
    imageList.push(newImage);
}

class Home extends React.Component {
    constructor() {
        super();
        this.state = {
            images: [],
        }
    }

    componentDidMount() {
        this.setState({ images: imageList });
    }

    render() {
        let imagesFinal = [];
        for (var image in this.state.images) {
            console.log(this.state.images[image].src);
            if (this.state.images[image].naturalHeight > this.state.images[image].naturalWidth) {}
            imagesFinal.push(<img src={this.state.images[image].src} className='landscape-img' alt=''></img>);
        }

        return <div>{imagesFinal}</div>;
    }
}

export default Home;
从“React”导入React;
导入'bootstrap/dist/css/bootstrap.css';
导入“./index.css”;
var imageList=[];
函数输入(r){
常量键=r.键();
让图像={};
for(键中的变量k){
图像[keys[k]。替换('./','')=r(keys[k]);
}
返回图像;
}
const images=importAll(require.context(“./images/resized/”,false,/\(png | jpe?g | svg)$/);
用于(图像中的var图像){
var newImage=新图像(图像[Image],图像[Image],空);
newImage.name=图像[图像];
newImage.src=images[image];
imageList.push(newImage);
}
类Home.C
// imageList.js

import foo from './images/foo.jpg'
import bar from './images/bar.jpg'
import baz from './images/baz.jpg'
import blah from './images/blah.jpg'

export default {
  foo,
  bar,
  baz,
  blah,
}
// __tests__/imagesList.test.js

import imageList from '../imageList'
import fs from 'fs'
import path from 'path'

const dir = path.join(__dirname, '..', 'images')

it('has all the images', () => {
  const imageFiles = fs.readdirSync(dir).filter((file) => {
    return path.extname(file).match(/\.(png|jpe?g|svg)$/)
  })

  expect(Object.keys(imageList)).toEqual(imageFiles)
})
#!/usr/bin/env node

const { readdirSync, writeFileSync } = require('fs')
const { extname, join } = require('path')

const relPath = (...paths) => join(__dirname, ...paths)
const dir = relPath('src', 'images')

const printLoaderFile = () => {
  const imageFiles = readdirSync(dir).filter((file) => {
    return extname(file).match(/\.(png|jpe?g|svg)$/)
  })

  const output = []

  imageFiles.forEach((file, index) => {
    output.push(`import image${index} from '${dir}/${file}'`)
  })

  output.push('\nexport default {')
  imageFiles.forEach((file, index) => {
    output.push(`  '${file}': image${index},`)
  })
  output.push('}\n')

  writeFileSync(relPath('src', 'imagesList.js'), output.join('\n'))
}

printLoaderFile()
import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import './index.css';

var imageList = [];

function importAll(r) {
    const keys = r.keys();
    let images = {};
    for (var k in keys) {
        images[keys[k].replace('./', '')] = r(keys[k]);
    }
    return images;
}

const images = importAll(require.context('./images/resized/', false, /\.(png|jpe?g|svg)$/));

for (var image in images) {
    var newImage = new Image(images[image], images[image], null);
    newImage.name = images[image];
    newImage.src = images[image];
    imageList.push(newImage);
}

class Home extends React.Component {
    constructor() {
        super();
        this.state = {
            images: [],
        }
    }

    componentDidMount() {
        this.setState({ images: imageList });
    }

    render() {
        let imagesFinal = [];
        for (var image in this.state.images) {
            console.log(this.state.images[image].src);
            if (this.state.images[image].naturalHeight > this.state.images[image].naturalWidth) {}
            imagesFinal.push(<img src={this.state.images[image].src} className='landscape-img' alt=''></img>);
        }

        return <div>{imagesFinal}</div>;
    }
}

export default Home;