我正在尝试在React中制作一个相册组件,该组件从Firebase Storage检索照片网址,并将它们添加到带有React Hooks的状态中。问题是,即使我可以看到图像URL通过React Chrome扩展程序正确设置为状态,也不会创建<img/>
标签。
组件的完整代码:
import React, {useEffect, useState} from 'react';
import {Fab} from "@material-ui/core";
import AddIcon from '@material-ui/icons/Add';
import {colorTheme} from "../constants/colors";
import firebase from 'firebase/app';
import '@firebase/firestore';
import '@firebase/auth';
import '@firebase/storage';
export default function PhotoAlbum() {
const storageRef = firebase.storage().ref();
const [images, setImages] = useState([]);
useEffect(() => {
loadImages();
}, []);
function loadImages() {
let imageUrls = [];
const imagesRef = storageRef.child('/images');
imagesRef.listAll().then(res => {
res.items.forEach(resItem => {
resItem.getDownloadURL().then( url => {
imageUrls.push(url)
})
})
}).then(() => setImages(imageUrls)); // I think this works, I can see the urls on the state
}
function handleChange(e) {
let files = e.target.files;
for(let i = 0; i < files.length; i++){
const file = files[i];
storageRef
.child( `/images/${file.name}` )
.put(file)
.then( () => {
console.log( "Added file to storage! ", file.name );
});
}
}
return (
<div>
{images.map((url, index) => (
<img src={url} key={index.toString()} alt={'this is an image'}/> // These are never rendered
))}
<div style={styles.floatingContainer}>
<input
accept="image/*"
style={styles.input}
id="contained-button-file"
multiple
type="file"
onChange={handleChange}
/>
<label htmlFor={"contained-button-file"}>
<Fab
color='primary'
aria-label='add'
style={styles.floatingButton}
component="span">
<AddIcon/>
</Fab>
</label>
</div>
</div>
)
}
const styles = {
floatingContainer: {
borderRadius: '30px',
position: 'absolute',
right: '2vw',
bottom: '2vh'
},
floatingButton: {
backgroundColor: colorTheme.darkGreen,
},
input: {
display: 'none',
},
};
我对React不太熟悉,我确信我只是误解了一些东西。我非常感谢您的提示和帮助!
我实际上解决了这个问题,问题在于加载图像时我没有更新状态,我只是将它们推到数组中,所以视图从未重新渲染。我将其更改为:
function loadImages() {
const imagesRef = storageRef.child('/images');
imagesRef.listAll().then(res => {
res.items.forEach(resItem => {
resItem.getDownloadURL().then(url => {
setImages(oldArray => [...oldArray, url]) // This line has changed!
})
})
});
}
现在可以了!