#javascript #html #reactjs #react-native #smartcontracts
Вопрос:
Здравствуйте, мне было интересно, есть ли у кого-нибудь следующая проблема(Необработанный отказ (ошибка типа): информация.контракт.методы не определены): введите описание изображения здесь
Вот где информация получает настройку const intialInfo = { подключено: ложь, статус: ноль, учетная запись: ноль, контракт: ноль, }; const intialDropState = { загрузка: ложь, список:[], }; console.log(контракт);
const DropList = () =gt; {
const [info, setInfo] = useState(intialInfo); const [drops,setDrops] = useState(intialDropState);
**Мой смарт-контракт вызывает getDrops, выполнив следующие действия:
//Get the NFT drop objects list function getDrops() public view returns(Drop[] memory) { return drops; }
**
вот та часть кода, в которой есть проблема
const getDrops = async() =gt; { setDrops(prevState =gt; ({ ...prevState, loading: true, })); info.contract.methods .getDrops() .call() .then((res) =gt; { console.log(res); setDrops({ loading: false, list: res, }); }) .catch((err) =gt; { console.log(err); setDrops(intialDropState); }); };
Вот код
Я сфотографировал весь свой код на следующих фотографиях: введите описание изображения здесь
введите описание изображения здесь
import contract from "../contract/contract.json"; import Web3 from "web3"; import {useState, useEffect} from "react"; const intialInfo = { connected: false, status: null, account: null, contract: null, }; const intialDropState = { loading: false, list:[], }; console.log(contract); const DropList = () =gt; { const [info, setInfo] = useState(intialInfo); const [drops,setDrops] = useState(intialDropState); // connecting to metamask and inital state of web dapp const init = async() =gt; { //Connect to blockchain to metamask if there is a metamask if(window.ethereum.isMetaMask){ const accounts = await window.ethereum.request({ method: "eth_requestAccounts", }); const networkId = await window.ethereum.request({ method: "net_version", }); //network == 4 for testnet for ETH use networkId == 1 if(networkId === 4){ let web3 = new Web3(window.ethereum); setInfo({ ...intialInfo, connected: true, account: accounts[0], contract: new web3.ethereum.Contract(contract.abi, contract.address), }); } else{ setInfo({ ...intialInfo, status: "You need to be on the Ethereum testnet."}); } } else{ setInfo({ ...intialInfo, status: "You need metamask."}); } }; const initOnChange = () =gt; { if(window.ethereum){ window.ethereum.on("accountsChanged", () =gt;{ window.location.reload(); }); window.ethereum.on("chainChanged", () =gt;{ window.location.reload(); }); } }; const getDrops = async() =gt; { setDrops(prevState =gt; ({ ...prevState, loading: true, })); info.contract.methods .getDrops() .call() .then((result) =gt; { console.log(result); setDrops({ loading: false, list: result, }); }) .catch((err) =gt; { console.log(err); setDrops(intialDropState); }); }; useEffect(() =gt; { init(); initOnChange(); }, []); return ( lt;divgt; lt;button onClick={() =gt; getDrops()}gt;Get Drops lt;/buttongt; {drops.loading ? lt;pgt;Loadinglt;/pgt; : null} lt;/divgt; ); }; export default DropList;
Комментарии:
1. Вы не показываете, откуда
info
это исходит. Вероятно, переменная еще не инициализирована , или у нее просто ее нетcontract
, илиcontract
у нее нет никакого метода.2. Можете ли вы отредактировать свой вопрос, указав дополнительную информацию об этой информационной переменной? Похоже, проблема в этом
Ответ №1:
Я думаю, что проблема в эффекте использования
useEffect(() =gt; { init(); initOnChange(); }, []);
Вы должны передать зависимости,
useEffect(() =gt; { init(); initOnChange(); // as far as I see, those are the only dependencies }, [window.ethereum,info]);
затем в jsx, чтобы избежать сбоя вашего приложения:
info amp;amp; info.contract amp;amp; info.contract.methods
или, в зависимости от ваших пакетов, вы можете использовать это
info?.contract?.methods