- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到的情况是,第一次加载页面时,应该在 Home.js
中加载的图像没有加载,直到在浏览器上推送刷新(Chrome ).这种情况发生在开发服务器和实时生产服务器中,有时必须多次刷新才能显示图像。
请注意,我对所有 Web 开发以及 React 都是新手,因为我的大部分经验都是在 Android 开发方面。
我认为这与我将图像加载到 Home 组件的方式有关。通过日志记录,我发现图像是在页面加载之前加载的(使用 componentDidMount()
),所以我正在寻找任何可用的解决方案。
谢谢,这是代码...
主要.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;
首页.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 {
render() {
let images = imageList.map(image => {
if (image.naturalHeight > image.naturalWidth) { // portrait
return <img className='portrait-img' src={image.src} alt=''/>
} else if (image.naturalHeight < image.naturalWidth) { // landscape
return <img className='landscape-img' src={image.src} alt=''/>
}
});
return (
<div>
{images}
</div>
);
}
}
export default Home;
index.css:
body {
background-color: #FFF;
padding: 20px;
margin: 0;
font-family: Helvetica;
}
h1 {
color: #111;
font-weight: bold;
padding-top: 2px;
}
ul.header li {
display: inline;
list-style-type: none;
margin: 0;
}
ul.header {
background-color: #111;
padding: 0;
}
ul.header li a {
color: #FFF;
font-weight: bold;
text-decoration: none;
padding: 20px;
display: inline-block;
}
.content {
background-color: #FFF;
padding: 20px;
}
.content h2 {
padding: 0;
margin: 0;
}
.content li {
margin-bottom: 10px;
}
.active {
background-color: #0099FF;
}
.portrait-img {
max-width: 55%;
height: auto;
padding: 5px;
}
.landscape-img {
max-width: 75%;
height: auto;
padding: 5px;
}
.navbar {
max-height: 110px;
background-color: #FFCC00 !important;
}
.content {
padding-top: 80px;
}
footer {
background-color: #FFF;
font-size: 7pt;
position: relative;
margin: auto;
float: left;
}
.social-media-link {
color: #111;
}
::-webkit-scrollbar {
display: none;
}
@media only screen and (max-width: 500px) {
h1 {
font-size: 18pt;
}
.navbar {
max-height: 120px;
}
.content {
padding-top: 104px;
}
.header {
font-size: 10pt;
}
.portrait-img {
max-width: 100%;
height: auto;
padding: 2px;
}
.landscape-img {
max-width: 100%;
height: auto;
padding: 2px;
}
footer {
font-size: 5pt;
}
.social-media-link {
padding: 5px;
}
}
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>
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import Main from './Main';
import './index.css';
ReactDOM.render(
<Main />,
document.getElementById('root'),
);
编辑:
修改了下面的 Home.js 以使用 Promise。这里的想法是,渲染图像的 Promise 将改变 this.state.images
并且该值将在 Component 的 render()
返回的 HTML 中使用.这并不能解决问题,但是,它确实会导致记录 imgs
列表,而不是像以前那样记录 undefined
列表。
import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import './index.css';
import { resolve } from 'q';
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(props) {
super();
this.state = {
images: null,
};
}
componentDidMount() {
let promise = this.getImages();
promise.then(result => {
let images = result.map(image => {
if (image.naturalHeight > image.naturalWidth) { // portrait
return <img className='portrait-img' src={image.src} alt='' />
} else if (image.naturalHeight < image.naturalWidth) { // landscape
return <img className='landscape-img' src={image.src} alt='' />
}
});
this.setState({ images: images });
}, function(error) {
this.setState({ images: error });
});
}
getImages() {
let promise = new Promise((resolve, reject) => {
let imageList = [];
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);
}
if (imageList.length > 0) {
console.log(imageList);
resolve(imageList);
} else {
console.log('shit');
reject(Error('oh shit'));
}
});
return promise;
}
render() {
return (
<div>
{this.state.images}
</div>
);
}
}
export default Home;
这导致:
硬重载后(ctrl+F5):images = [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
刷新后(ctrl+R):images = [{...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}]
- 都带有 typeof : Symbol(react.element),类型:“img”
。
最佳答案
console.log
不保证是同步的,因此您不能依赖它来确定执行顺序。有些引擎是,有些不是。
我也不会依赖 require.context
,尤其是当您使用 create-react-app
时。请参阅:https://github.com/facebook/create-react-app/issues/517
一般来说,如果您的元素已经为 ES 模块设置好并且您发现自己需要 require
,那么在我看来,这有点代码味道。 ES 模块的全部意义在于使作用域成为静态的,而不是动态的,这样编译器就可以推断出在缩小时要丢弃什么。目录结构在运行时实际上不再存在;它全部被缩小到一个大文件中,或者由 webpack 开发服务器即时压缩,或者作为生产构建的一部分。
文件是否太多而无法直接导入到模块中?您可以为 imageList
设置一个单独的模块来处理加载并导出它,然后只需 import
并直接在您的组件中使用:
// 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,
}
然后您可以进行测试以确保将来不会遗漏任何一个(注意,测试直接在节点中使用文件结构运行,而不是 webpack-ed 最终产品):
// __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)
})
如果真的太多了,或者它们会经常变化,我通常喜欢在命令行上自动创建代码。下面是快速 n 脏,但应该接近你需要的,具体取决于路径:
#!/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()
关于javascript - Home 组件仅在刷新时加载(而不是在初始加载时),竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54431391/
我们知道,当使用 hibernate 对数据库进行批量更新时(即使在 HQL 中),所做的更改不会复制到存储在当前 session 中的实体。 所以我可以调用 session.refresh 来加载对
我正在做一个项目,所有的东西都保存在事件中,所以服务器需要一些时间来响应新数据。我正在使用 Fluent 等待使用 ajax 的页面,但是这个不使用任何 ajax。所以我想刷新页面检查是否有新项目,如
我有一个从 Vector 创建的 JTable。 如何刷新 JTable 以显示添加到 Vector 的新数据? 最佳答案 当 TableModel 发生更改时,您的 JTable 应该会自动更新。我
有没有办法使用下面的代码来刷新已经存在的 div id,而不是刷新时间? window.onload = startInterval; function startInterval() {
我更新了在 Shiny Server 上运行的 Shiny 应用程序使用的 DataSet.RData。但是, Shiny 的应用程序仍在旧数据上运行。我已通过浏览器历史记录清除并重新启动浏览器几次,
我的应用程序中有一个无限滚动的网格面板(ExtJs 4.2.1),类似于 this example .用户可以单击刷新按钮,然后必须使用数据库中的数据更新网格的行。我在刷新按钮处理程序中调用 stor
我不知道这三种方法中哪一种最适合我。他们都为我工作。有谁知道刷新、更新和重画之间的区别吗? 最佳答案 根据在线文档: Refresh - 重新绘制屏幕上的控件。 Call Refresh method
有什么办法吗 ICollectionView.Refresh() 或者 CollectionViewSource.GetDefaultView(args.NewValue).Refresh(); 在
这个问题已经有答案了: Updating address bar with new URL without hash or reloading the page [duplicate] (4 个回答)
我有一个 javascript 设置超时以在 10 秒后关闭 div,并且我想在 div 关闭时添加页面刷新。我正在使用的代码如下。 var container_close_sec = "1
我有一组具有以下名称的页面.... update1.php update2.php update3.php update4.php update5.php update6.php update7.ph
如果是则触发js函数。我可以使一个复选框保持选中状态,并在页面刷新时检查值并选中“checked”,并提交以下内容... checked="checked" /> 你都不记得触发js函数。 这是我的
我正在尝试刷新 php 脚本以在数据库更新时显示更新的内容。我首先构建了我的 php,然后刷新代码,然后合并它们。但是,脚本不会更新。有谁知道为什么吗? $(document).ready
当我要删除的节点扩展集合类型时,Grails中有一个错误阻止我使用removeFrom *。直接从关联中删除节点不会更新二级缓存。 A hasMany B 有什么方法可以使关联缓存手动无效或强制重新加
我正在使用 hibernate 和 mysql 来抽象一个数据库,以便在 java 驱动的网站中使用。我使用 hibernate 很好地解决了所有查询,但似乎无法弄清楚如何使用它进行更新、插入和删除,
如何通过调用 oncreateview 方法重新创建 fragment ?我有一个 fragment ,用于通过表单插入新数据,单击按钮后,我想通过删除在 EditText 中输入的数据来重新创建 f
当我从一个到另一个时,我试图刷新我的观点。我知道我应该将刷新代码放在 viewWillAppear 中,但我不知道该放什么代码。 你们能帮帮我吗? 谢谢! 最佳答案 在您看来,请调用 setNeeds
我正在开发 iPhone 应用程序并希望使用: CFStreamCreatePairWithSocketToHost(NULL, url, port, &serverReadStream, &serv
看到我已经创建了一个用于登录用户的脚本。而且我还添加了设置选项卡,以便用户可以编辑他们的设置!但是当我尝试它时,mysql 表中的数据发生了变化,但配置文件中显示的用户名和用户电子邮件保持不变!当我注
好的。这就是它的样子。 当我启动应用程序时,我从服务器收到的第一件事是数据: {name: "test", type: "checkbox" checked: true, } 这使得其中一个复选框
我是一名优秀的程序员,十分优秀!