React 页面不会加载映射元素,直到再次调用它们
React page won't load mapped elements until calling them again
我有一个用于智能合约的 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.map((项目, i) => (
我也认为您的数据(状态)在呈现页面时不可用
我已经按照其他问题的答案修复了错误:
"你正在调用 setNumbers 并将它传递给它已有的数组。你已经更改了其中一个值,但它仍然是同一个数组,我怀疑 React 没有看到任何原因重新渲染,因为状态没有改变;新数组是旧数组。"
避免这种情况的一个简单方法是将数组展开到一个新数组中:
setNumbers([...old])
现在可以了。
我有一个用于智能合约的 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.map((项目, i) => (
我也认为您的数据(状态)在呈现页面时不可用
我已经按照其他问题的答案修复了错误:
"你正在调用 setNumbers 并将它传递给它已有的数组。你已经更改了其中一个值,但它仍然是同一个数组,我怀疑 React 没有看到任何原因重新渲染,因为状态没有改变;新数组是旧数组。"
避免这种情况的一个简单方法是将数组展开到一个新数组中: setNumbers([...old])
现在可以了。