9

I apologize preemptively for the very basic question. I have added and installed web3 using yarn in my react project. Inside my index.js file in /scr and based on the web3 docs I have tried both (not at the same time)

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

and

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

before adding

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]));

and end up with an error complaining "Cannot read property 0 of undefined" leading me to think the issue is with accounts[0].

Confusingly, when my require/import statements at the top of the page are deleted and the page is refreshed, the browser detects metamask and prints my address to the console. Additionally I get complaints that my web3 object is undefined but that is to be expected.

I have not explicitly run webpack or browserify because webpack is included in react projects. Is this something I need to do?

What is going on here and how can I get my React project to work with metamask?

3 Answers 3

7

It sounds confusing and basing on the version of web3 you have the syntax is different. According to the error you got at the first place seems like you are using web3 1.0. However the instance code is for the version 0.2.x.x

Just to clarify, this is how your code will look like in case you're using web3 1.0

import Web3 from 'web3';

const web3 = new Web3(Web3.givenProvider || "http://localhost:8545");
web3.eth.getAccounts().then(console.log);

So basically you create an instance of web3 with the givenProvider (in case you're using metamask or mist) or with the local. Then you get your accounts.

In case you're using the old version of web3 the code is slightly different:

import Web3 from 'web3';

let web3 = null;
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(callback(error, result){ console.log(result) })
1
  • Thanks! I thought I was using the old version because 1.0 is still in beta but yarn add web3 automatically installed 1.0 Commented Mar 22, 2018 at 21:52
3

The simplest way is to use react-web3-provider component.

Add the Web3Provider to your root React component:

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>
)

Then in component where you want to use 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);
0

As of July 2019, your best shot is web3-react. Take a look at how it's used in Uniswap.

Sneak peek:

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')
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.