簡體   English   中英

安裝 Metamask 時 React 不渲染

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM