reactjs - React 页面不会加载映射的元素,直到再次调用它们
问题描述
我有一个用于我制作的智能合约的 React dApp。在我通过单击名为“All Cryptonauts”的按钮进入的应用程序之一中,如下面的屏幕显示所示,我尝试调用我的智能合约的所有铸造 NFT。我可以成功地获取它们并将它们全部映射,但起初,什么都没有出现。
但是,再次单击“所有 Cryptonauts”按钮后,所有预期的数据都会显示出来。
下面是我页面的代码。我认为我的问题在于渲染,所以我进行了一些研究,有人说他们避免手动重新渲染并解决从 HTML 代码中删除关键属性的相同问题,但这对我不起作用并且有错误当我移除钥匙时,在控制台中。我也不能在这里使用 this.setState 。任何人都可以帮助我以正确的方式做我想做的事吗?谢谢!
export const AllCryptonauts = (props) => {
const web3 = window.web3;
var [currentAccount, setCurrentAccount] = useState("0x0");
let [model, setModel] = useState([]);
let lastMintJson;
let supply = [];
let myNFTs = [];
useEffect(() => {
window.ethereum.on('chainChanged', (_chainId) => checkChainID());
window.ethereum.on('accountsChanged', (_accounts) => loadBlockchainData());
checkChainID();
return () => { }
}, [currentAccount])
async function checkChainID() {
const networkId = await web3.eth.net.getId();
if (networkId !== 4) {
props.history.push("/")
} else {
loadBlockchainData();
}
}
async function loadBlockchainData() {
window.web3 = new Web3(window.ethereum);
const accounts = await web3.eth.getAccounts();
setCurrentAccount(accounts[0]);
loadContract();
}
async function loadContract() {
if (currentAccount.length > 5) {
const ContractObj = impContract;
supply = await ContractObj.methods.totalSupply().call();
setAllMints(supply);
}
}
async function setAllMints(supply) {
for (var i = 1; i <= parseInt(supply, 10); i++) {
lastMintJson = "https://cors-anywhere.herokuapp.com/https://nftornek.000webhostapp.com/cryptonauts/json/" + i + ".json";
let res = await axios.get(lastMintJson);
res.data.imagelink = "https://nftornek.000webhostapp.com/cryptonauts/image/" + i + ".png"
myNFTs.push(res.data);
}
setModel(setNFTModel(myNFTs));
}
function setNFTModel(jsonObj) {
for (var i = 0; i < jsonObj.length; i++) {
model[i] = {
dna: jsonObj[i].dna,
name: jsonObj[i].name,
edition: jsonObj[i].edition,
imagelink: jsonObj[i].imagelink,
attributes: jsonObj[i].attributes
};
}
return model;
}
return (
<div>
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}><img src="https://nftornek.000webhostapp.com/frontend/cnlogo.png" width='500' height='180' alt=""></img></div>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<button className="regularButton divide" onClick={MintPage}>Mint</button>
<button className="regularButton divide" onClick={MyCryptonauts}>My Cryptonauts</button>
<button className="regularButton divide" onClick={AllCryptonauts}>All Cryptonauts</button>
<button className="regularButton divide" onClick={Disconnect}>Disconnect</button>
</div>
<div style={{ display: 'flex', justifyContent: 'center' }}><p className="accountText">Current Account: {currentAccount}</p></div>
{model.map((item, i) => (
<div key={i} style={{ display: 'flex', justifyContent: 'center', marginBottom: '30px', height: '350px' }}>
<div style={{ width: '350px', border: '2px solid #38495a', borderRadius: '5px' }}><img src={item.imagelink} alt=""></img>
</div>
<div style={{ width: '300px', padding: '10px', border: '2px solid #38495a', borderRadius: '4px', backgroundColor: 'rgba(56, 73, 90, 0.25)', color: '#38495a' }}><b>ID: {item.edition}<br></br> Name: {item.name}</b>
<table className="tableClass t1">
<tbody>
{item.attributes.map((attr, j) => (
<tr key={'attr' + ' ' + j}>
<td key={1}>{attr.trait_type}:</td>
<td key={2}>{attr.value}</td>
</tr>
))}
</tbody>
</table></div>
</div>
))}
</div>
)
}
解决方案
尝试这样的事情:
{model && model.map((item, i) => (
我还认为在呈现页面时您的数据(状态)不可用
推荐阅读
- spring - Spring Boot - 使用@Transactional 进行测试危险吗?
- amazon-web-services - 如何在不将 zip 文件下载到硬盘的情况下将数据集从 zip 文件上传到 s3 存储桶?
- maven - Maven 配置文件插件
- node.js - 使用 npm 在 linux (yocto) 上更新 nodejs
- mongodb - 需要在 Mongoose 中获取按外键分组的记录列表
- ios - iOS 在 TestFlight 版本中崩溃
- javascript - 扩大 div 的宽度以缩小另一个
- datastage - 通过非结构化数据阶段连接到 XLSX 文件时处理 Null 值
- wordpress - 在图像 url 末尾添加斜杠显示 WP+Nginx-fpm 上的主页内容
- excel - Excel VBA检查多个复选框