Problem:
After fetching my server for image’s width and height, adding that and image’s link to a state called imageList
and then mapping over the imageList to create an <Art />
component, which returns a <Image />
(component imported from Drei’s library) component with all the props passed down to it, the <Image />
component doesn’t seem to render at all and no errors are displayed as well.
What would need to happen
After passing down the props to <Image />
component, the <Canvas />
should render every mapped element of imageList state.
Extra info
The url that I pass down to <Image />
component is the url you get from Firebase’s storage ( the url of the image that’s stored in Firebase’s storage)
If there’s still some info required, don’t mind asking for it. Thanks to any helpers from the future.
Code below
App.jsx
import './App.css'
import { useEffect, useState, useRef, Suspense } from "react"
import {storage} from "./firebase"
import { getDownloadURL, listAll, ref, uploadBytes } from "firebase/storage"
import { v4 } from "uuid"
import { Canvas } from "@react-three/fiber"
import { OrbitControls } from '@react-three/drei'
import Art from "./components/Art.jsx"
import Loading from "./components/Loading.jsx"
function App() {
const [user, setUser] = useState("volzey")
const [imageUpload, setImageUpload] = useState(null)
const [imageList, setImageList] = useState([])
const firstRenderRef = useRef(true)
const imageListRef = ref(storage, `${user}/`)
useEffect(() => {
if (firstRenderRef.current) {
firstRenderRef.current = false;
return;
}
listAll(imageListRef)
.then((res) => {
res.items.forEach((item) => {
getDownloadURL(item)
.then((url) => {
fetch(`http://localhost:8080/getsize`, {
method: "POST",
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(url)
})
.then(res => res.json())
.then((data) => {
console.log(data)
setImageList((prev) => {
console.log(prev)
return [...prev, {url: data.url, width: data.width, height: data.height}]
})
})
.catch(err => console.log(err))
})
})
})
}, [])
const uploadImage = () => {
if (imageUpload == null) return;
const imageRef = ref(storage, `${user}/${imageUpload.name + v4()}`)
uploadBytes(imageRef, imageUpload).then((snapshot) => {
getDownloadURL(snapshot.ref)
.then((url) => {
fetch(`http://localhost:8080/getsize`, {
method: "POST",
mode: 'cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(url)
})
.then(res => res.json())
.then((data) => {
setImageList((prev) => {
console.log(`url: ${data.url}, width: ${data.width}, height: ${data.height}`)
return [...prev, {url: data.url, width: data.width, height: data.height}]
})
})
.catch(err => console.log(err))
})
})
}
return (
<div className="App-header">
<input type="file" onChange={(e) => {setImageUpload(e.target.files[0])}}/>
<button onClick={uploadImage}>Upload Image</button>
<Canvas>
<OrbitControls />
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Suspense fallback={<Loading />}>
{imageList.map((el, i) => {
<Art url={el.url} width={el.width} height={el.height} key={i} />
})}
</Suspense>
</Canvas>
</div>
)
}
export default App
Art.jsx
import React, {useRef} from "react"
import { Image, useAspect } from "@react-three/drei"
import { useFrame } from "@react-three/fiber"
const Art = (props) => {
const ref = useRef()
useFrame(() => {
ref.current.material.zoom = 1
ref.current.material.greyscale = 0
ref.current.material.color.set("hotpink")
})
const scale = useAspect(
props.width,
props.height,
1
)
return (
<Image url={props.url} scale={scale} ref={ref} />
)
}
export default Art;