我是初学者,正在阅读大量代码,现在我想知道下面的代码
我了解这段代码在做什么我需要澄清的是代码流。
我在运行它时看到图像加载:
- React 是从上到下执行代码的吗?
- PlaceholderImages 异步获取正确的图像,但是
App
如果需要时间,组件会开始渲染没有图像吗?如果是这样,我看不到任何setState
通知App
。我大概听错了!
此代码来自此Sandbox。
这是 index.js
import React from "react";
import ReactDOM from "react-dom";
import Masonry from "./Masonry";
import VerticalMasonry from "./VerticalMasonry";
import { sample, uniqueId } from "lodash";
import PlaceholderImages from "./PlaceholderImages";
import ItemRenderer from "./ItemRenderer";
PlaceholderImages().then(images => {
function addItems(amount = 10) {
return new Array(amount).fill("").map(i => {
const id = uniqueId();
const image = sample(images);
const width = 480;
const height = Math.round((480 / image.width) * image.height);
const imageUrl = `https://picsum.photos/${width}/${height}?image=${
image.id
}`;
return {
id,
key: id,
ratio: 1 / (image.width / image.height),
backgroundImage: `url(${imageUrl})`,
background: `rgb(${Math.ceil(Math.random() * 256)}, ${Math.ceil(
Math.random() * 256
)}, ${Math.ceil(Math.random() * 256)})`,
title: "Lorem ipsum dolor sit amet",
description:
"At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
};
});
}
let Items = addItems();
class App extends React.Component {
state = {
columns: 3,
items: Items,
gutter: 16,
outerGutter: true,
debug: true,
vertical: true
};
addItems() {
this.setState({
items: this.state.items.concat(addItems(20))
});
}
render() {
const {
items,
width,
gutter,
outerGutter,
debug,
vertical,
fullscreen
} = this.state;
const LeComponent = vertical ? Masonry : VerticalMasonry;
return (
<div>
<div
style={{
position: fullscreen && "absolute",
zIndex: 2
}}
>
<label htmlFor="gutter">Gutter</label>
<input
id="gutter"
type="number"
step={1}
min={0}
max={32}
value={gutter}
onChange={e => {
this.setState({
gutter: parseInt(e.target.value)
});
}}
/>
<button
onClick={() => this.setState({ outerGutter: !outerGutter })}
>
Outer Gutter: {outerGutter ? "On" : "Off"}
</button>
<button onClick={() => this.setState({ debug: !debug })}>
debug
</button>
<button onClick={() => this.setState({ vertical: !vertical })}>
{vertical ? "Vertical" : "Horizontal"}
</button>
<button onClick={() => this.setState({ width: 360 })}>360</button>
<button onClick={() => this.setState({ width: 480 })}>480</button>
<button onClick={() => this.setState({ width: 640 })}>640</button>
<button onClick={() => this.setState({ width: 728 })}>728</button>
<button onClick={() => this.setState({ width: 960 })}>960</button>
<button onClick={() => this.setState({ width: "100%" })}>
100%
</button>
<button onClick={() => this.setState({ fullscreen: !fullscreen })}>
{fullscreen ? "Fullscreen off" : "Fullscreen on"}
</button>
</div>
<div
style={{
width,
height: !fullscreen && 600,
position: fullscreen ? "initial" : "relative",
margin: "0 auto"
}}
>
<LeComponent
infinite
items={items}
itemRenderer={ItemRenderer}
gutter={gutter}
outerGutter={outerGutter}
extraPx={0}
debug={debug}
rows={{
0: 1,
320: 2,
480: 3,
640: 4
}}
cols={{
0: 1,
360: 2,
640: 2,
960: 3,
1280: 4,
1400: 5,
1720: 6,
2040: 7,
2360: 8
}}
onEnd={() => {
this.addItems();
}}
/>
<style>
{`body {
background-color: white;
}`}
</style>
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
});
这是 PlaceholderImages.js
import axios from "axios";
import { sampleSize } from "lodash";
export default async () => {
return new Promise((resolve, reject) => {
axios.get("https://picsum.photos/list").then(res => {
console.log(res.data[0]);
return resolve(sampleSize(res.data, 50));
});
});
};