My code is displaying the output twice for some reason and I cannot figure it out. Any help would be appreciated. this is the output that i am getting now . I believe it is something to do with setting setImagesCount. I tried transposing this from a class component to functional component, so I am not sure if i did it all correctly. i would like to sort them by id, but I am not able to figure out how to do it. in addition, is there a way to set up a custom search/map parameter, such as the wallet address to get their posts.
import Decentragram from "../build/contracts/Decentragram.json";
import Web3 from "web3";
import { useState, useEffect } from "react";
const Home = () => {
const ipfsClient = require("ipfs-http-client");
const ipfs = ipfsClient({
host: "ipfs.infura.io",
port: 5001,
protocol: "https",
});
const [account, setAccount] = useState("");
const [decentragram, setDecentragram] = useState(null);
const [images, setImages] = useState([]);
const [loading, setLoading] = useState(true);
const [imagesCount, setImagesCount] = useState(0);
const [buffer, setBuffer] = useState(null);
useEffect(() => {
loadWeb3();
loadBlockchainData();
}, []);
const loadWeb3 = async () => {
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
await window.ethereum.request({ method: "eth_requestAccounts" });
} else if (window.web3) {
window.web3 = new Web3(window.web3.currentProvider);
} else {
window.alert(
"Non-Ethereum browser detected. You should consider trying MetaMask!"
);
}
};
const loadBlockchainData = async () => {
const web3 = window.web3;
const accounts = await web3.eth.getAccounts();
setAccount(accounts[0]);
const networkId = await web3.eth.net.getId();
const networkData = Decentragram.networks[networkId];
if (networkData) {
const decentragram = new web3.eth.Contract(
Decentragram.abi,
networkData.address
);
setDecentragram(decentragram);
const imagesCount = await decentragram.methods.imageCount().call();
setImagesCount(imagesCount);
for (let i = 1; i <= imagesCount; i++) {
const image = await decentragram.methods.images(i).call();
setImages((prevImages) => [...prevImages, image]);
}
setImagesCount(imagesCount);
setLoading(false);
} else {
window.alert("Smart contract not deployed to detected network.");
}
};
const captureFile = async (event) => {
event.preventDefault();
const file = event.target.files[0];
const reader = new window.FileReader();
reader.readAsArrayBuffer(file);
reader.onloadend = () => {
setBuffer(Buffer(reader.result));
};
};
const uploadImage = async (description) => {
console.log("Submitting file to ipfs...");
ipfs.add(buffer, (error, result) => {
console.log("File was stored at Hash:", result);
if (error) {
console.error(error);
return;
}
setLoading(true);
decentragram.methods
.uploadImage(result[0].hash, description)
.send({ from: account })
.on("transactionHash", (hash) => {
setLoading(false);
});
});
};
return (
<div>
<form
onSubmit={(event) => {
event.preventDefault();
const description = document.getElementById("imageDescription").value;
uploadImage(description);
}}
>
<input
type="file"
accept=".jpg, .jpeg, .png, .bmp, .gif"
onChange={captureFile}
/>
<input
id="imageDescription"
type="text"
placeholder="Image description..."
required
/>
<button type="submit" class="btn btn-primary btn-block btn-lg">
Upload!
</button>
</form>
{images.map((image, key) => {
return (
<div key={key}>
<img src={image.hash} alt={image.description} />
<p>{image.description}</p>
</div>
);
})}
</div>
);
};
export default Home;