, поэтому я пытаюсь получить изображения из хранилища Firebase, а затем отобразить их в компоненте React. Честно говоря, я новичок в React / Javascript, и мне трудно понять асинхронный характер React / JS, и я столкнулся с проблемой, когда мои изображения загружаются, но компонент не повторно отображается после завершения выборки ...
Это код на моей главной странице, в функции useEffect я пытаюсь получить изображения, а затем сохранить их URL-адреса загрузки в массиве, а затем установить этот массив в состоянии (при загрузке страницы, т.е. только один раз). Поскольку это обещания, это не происходит синхронно, и когда я впервые загружаю страницу, на ней не отображаются изображения. Однако если я щелкну другой компонент на странице, он повторно отобразит мой компонент «Изображения», и изображения появятся (??), поэтому я знаю, что выборка сработала.
let storageRef = firebase.storage().ref()
let calendarRef = React.createRef()
const position = props.location.state.name.indexOf("@")
const username = props.location.state.name.substring(0, position);
const [simpleDate, setSimpleDate] = useState(null)
const [selectedDate, setSelectedDate] = useState('')
const [showModal, setShowModal] = useState(false)
const [showCancelModal, setShowCancelModal] = useState(false)
const [expectedPeople, setExpectedPeople] = useState(null)
const [events, setEvents] = useState([])
const [helpModal, showHelpModal] = useState(false)
const [pictureURLs, setPictureURLs] = useState([])
useEffect(() => {
//load pictures
const fetchImages = async () => {
let urls = []
storageRef.child('cabinPictures').listAll().then((result) => {
result.items.forEach((imageRef) => {
imageRef.getDownloadURL().then(url => {
urls.push(url)
})
})
})
return urls;
}
fetchImages().then(urls => {
setPictureURLs(urls);
console.log("inside .then() " + pictureURLs)
})
//fetch reservations
firebase
.firestore()
.collection('reservations')
.onSnapshot(serverUpdate => {
const reservations = serverUpdate.docs.map(_doc => {
const data = _doc.data();
data['id'] = _doc.id;
return data;
});
let fetchedEvents = reservations.map(reservation => {
let date = reservation.reservationDate.toDate()
const month = ("0" + (date.getUTCMonth() + 1))
let dateString = date.getUTCFullYear() + "-" + ("0" + (date.getUTCMonth()+1)).slice(-2) + "-" + ("0" + date.getUTCDate()).slice(-2)
return {title: reservation.username + " - " + reservation.numPeople + " total", date: dateString, id: reservation.id, totalPeople: reservation.numPeople, month: month}
})
console.log(fetchedEvents)
setEvents(fetchedEvents)
});
}, [])
Мои изображения компонент на главной странице, где запускается useEffect (см. выше). Я передаю URL-адреса из состояния в качестве опоры:
<div className="pictures-div-container">
<Pictures pictureURLs={pictureURLs}>
</Pictures>
</div>
Код для моего компонента Picture:
import React, { useState, useEffect } from 'react'
import styles from "./styles.css"
const firebase = require('firebase');
const Pictures = (props) => {
const [uploadImage, setUploadImage] = useState(null)
const [progressValue, setProgressValue] = useState(0)
let storageRef = firebase.storage().ref()
let { pictureURLs } = props
const handleUpload = () => {
setProgressValue(0)
const uploadTask = storageRef.child(`cabinPictures/${uploadImage.name}`).put(uploadImage)
uploadTask.on('state_changed',
(snapshot) => {
//progress function
const progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes ) * 100)
setProgressValue(progress)
},
(error) => {
//error function
console.log(error)
},
() => {
//complete function
storageRef.child('cabinPictures').child(uploadImage.name).getDownloadURL().then(url => {
console.log(url)
} )
});
}
const handleFileSelect = (e) => {
if (e.target.files[0]) {
setUploadImage(e.target.files[0])
}
}
return (
<div className="pictures-container">
<h2>Upload a Picture!</h2>
<button className="upload-button" onClick={() => handleUpload()}>Upload</button>
<input type="file" onChange={(e) => handleFileSelect(e)}></input>
<progress value={progressValue} max="100"></progress>
<div className="pictures">
{
pictureURLs.map((url, index) => {
return <img className="picture" key={index} src={url}></img>
})
}
</div>
</div>
)
}
export default Pictures
Итак, может ли кто-нибудь помочь мне понять, почему компонент изображений не повторно- рендеринг автоматически, когда состояние установлено после получения URL-адресов изображений из firebase? Я думал, что при изменении опоры в компоненте, весь компонент перерисовывается? 1014 *
//fetch and load pictures
const fetchImages = async () => {
let result = await storageRef.child('cabinPictures').listAll();
let urlPromises = result.items.map(imageRef => imageRef.getDownloadURL())
return Promise.all(urlPromises)
}
const loadImages = async () => {
const urls = await fetchImages()
setPictureURLs(urls)
}
loadImages()