[英]React does not render when Metamask installed
我正在學習如何使用 Metamask 和 react.js 創建 web3 應用程序
我使用 create-react-app 並按照https://github.com/ChainSafe/web3.js#troubleshooting-and-known-issues來解決 polyfill 周圍的錯誤。
然后我按照https://docs.metamask.io/guide/onboarding-library.html#using-react使用 Metamsk 和 react。
當元掩碼未安裝到瀏覽器時,DOM 會按預期呈現,但在安裝時不會呈現。 它只在 body 標記中使用<div id='root></div>
。
為什么只有在安裝 Metamask 時才渲染? 任何想法?
App.js 是
import React from 'react';
import './App.css';
import Header from './components/Header/Header';
import Main from './components/Main/Main';
import Description from './components/Description/Description';
const App = () => {
return (
<div>
<Header />
<Main />
<Description />
</div>
)
}
export default App
主要的.jsx
import './main.css';
import React, { useState, useEffect, useRef } from 'react'
import Web3 from 'web3';
import OnboardingButton from './OnboardingButton'
const Main = () => {
return (
<div className="container container__main">
<OnboardingButton />
</div>
)
}
export default Main
OnboardingButton.jsx
import React, { useState, useEffect, useRef } from 'react'
import MetaMaskOnboarding from '@metamask/onboarding';
const ONBOARD_TEXT = 'Click here to install Metamask.'
const CONNECT_TEXT = 'Connect';
const CONNECTED_TEXT = 'Connected';
const OnboardingButton = () => {
const [buttonText, setButtonText] = useState(ONBOARD_TEXT);
const [isDisabled, setDisabled] = useState(false);
const [accounts, setAccounts] = useState([]);
const onboarding = useRef();
// execute only when DOM initialized
useEffect(() => {
if (!onboarding.current) {
onboarding.current = new MetaMaskOnboarding();
}
}, []);
useEffect(() => {
if (MetaMaskOnboarding.isMetaMaskInstalled()) {
if (accounts.length > 0) {
setButtonText(CONNECTED_TEXT);
setDisabled(true);
onboarding.current.stopOnboarding();
} else {
setButtonText(CONNECT_TEXT);
setDisabled(false);
}
}
}, [accounts]);
useEffect(() => {
function handleNewAccounts(newAccounts) {
setAccounts(newAccounts);
}
if (MetaMaskOnboarding.isMetaMaskInstalled()) {
window.ethereum.on('accountsChanged', handleNewAccounts);
return () => {
window.ethereum.off('accountsChanged', handleNewAccounts);
};
}
}, []);
const onClick = () => {
if (MetaMaskOnboarding.isMetaMaskInstalled()) {
window.ethereum
.request({ method: 'eth_requestAccounts' })
.then((newAccounts) => setAccounts(newAccounts));
} else {
onboarding.current.startOnboarding();
}
};
return (
<button disabled={isDisabled} onClick={onClick}>
{buttonText}
</button>
);
}
export default OnboardingButton
package.json 依賴項
"dependencies": {
"@metamask/onboarding": "^1.0.1",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4",
"web3": "^1.7.4"
}
首先,我注意到根據 Metamask 的教程,我跳過了將此代碼復制到第三個 useEffect() 中,但這不是解決方案。
window.ethereum
.request({ method: 'eth_requestAccounts' })
.then((newAccounts) => setAccounts(newAccounts));
我刪除了在初始化時請求連接 Metamask 的第三個 useEffect(),以某種方式成功呈現。 我個人認為 webapp 不應該在網站剛打開時請求連接到錢包,所以我不需要 Metamask 教程中的第三個 useEffect。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.