Как импортировать web3 в проект React

Заранее извиняюсь за очень простой вопрос. Я добавил и установил web3, используя пряжу в своем проекте реагирования. Внутри моего файла index.js в /scr и на основе документов web3 я пробовал оба (не одновременно)

var Web3 = require("web3");
var web3 = new Web3();

и

import Web3 from 'web3';
var web3 = new Web3();

перед добавлением

if (typeof web3 !== 'undefined') {
  web3 = new Web3(web3.currentProvider);
} else {
  // set the provider you want from Web3.providers
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

web3.eth.getAccounts((error, accounts) => console.log(accounts[0]));

и в конечном итоге с сообщением об ошибке «Невозможно прочитать свойство 0 неопределенного», что заставляет меня думать, что проблема связана с учетными записями [0].

Как ни странно, когда мои операторы require/import в верхней части страницы удаляются и страница обновляется, браузер обнаруживает метамаску и выводит мой адрес в консоль. Кроме того, я получаю жалобы на то, что мой объект web3 не определен, но этого следовало ожидать.

Я явно не запускал веб-пакет или браузер, потому что веб-пакет включен в реагирующие проекты. Это то, что мне нужно сделать?

Что здесь происходит и как заставить мой проект React работать с метамаской?

Ответы (3)

Это звучит запутанно, и в зависимости от версии web3 у вас другой синтаксис. Судя по ошибке, которую вы получили в первую очередь, похоже, что вы используете web3 1.0. Однако код экземпляра предназначен для версии 0.2.xx.

Просто чтобы уточнить, вот как будет выглядеть ваш код, если вы используете web3 1.0.

импортировать Web3 из «web3»;

const web3 = новый Web3(Web3.givenProvider || "http://localhost:8545");
web3.eth.getAccounts().then(console.log);

Таким образом, в основном вы создаете экземпляр web3 с givenProvider(если вы используете метамаску или туман) или с локальным. Затем вы получаете свои счета .

Если вы используете старую версию web3, код немного отличается:

импортировать Web3 из «web3»;

пусть web3 = ноль;
if (typeof web3 !== 'undefined') {
  web3 = новый Web3 (web3.currentProvider);
} еще {
  // устанавливаем нужного провайдера из Web3.providers
  web3 = новый Web3(новый Web3.providers.HttpProvider("http://localhost:8545"));
}

web3.eth.getAccounts (обратный вызов (ошибка, результат) { console.log (результат) })
Спасибо! Я думал, что использую старую версию, потому что 1.0 все еще находится в стадии бета-тестирования, но yarn add web3 автоматически установил 1.0.

Самый простой способ — использовать компонент react-web3-provider .

Добавьте в Web3Providerсвой корневой компонент React:

import Web3Provider from 'react-web3-provider';

ReactDOM.render(
  <Web3Provider
    defaultWeb3Provider={
      (cb) => cb(new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/YOUR_API_KEY")))
    }
    loading="Loading..."
  >
    <App />
  </Web3Provider>
)

Затем в компоненте, где вы хотите использовать Web3:

import { withWeb3 } from 'react-web3-provider';

class MyComponent {
  render() {
    const { web3 } = this.props;

    web3.eth.getAccounts(console.log);

    // Version 1.0.0-beta.35
    return "Web3 version: {web3.version}";
  }
}

export default withWeb3(MyComponent);

По состоянию на июль 2019 года ваш лучший вариант — web3-react . Посмотрите, как это используется в Uniswap .

Краткий обзор:

function ContextProviders({ children }) {
  return (
    <ApplicationContextProvider>
      <TransactionContextProvider>
        <TokensContextProvider>
          <BalancesContextProvider>
            <AllowancesContextProvider>{children}</AllowancesContextProvider>
          </BalancesContextProvider>
        </TokensContextProvider>
      </TransactionContextProvider>
    </ApplicationContextProvider>
  )
}

function Updaters() {
  return (
    <>
      <ApplicationContextUpdater />
      <TransactionContextUpdater />
    </>
  )
}

ReactDOM.render(
  <ThemeProvider>
    <>
      ...
      <Web3Provider connectors={connectors} libraryName="ethers.js">
        <ContextProviders>
          <Updaters />
          <App />
        </ContextProviders>
      </Web3Provider>
    </>
  </ThemeProvider>,
  document.getElementById('root')
)