Cómo importar web3 en un proyecto React

Pido disculpas preventivamente por la pregunta muy básica. Agregué e instalé web3 usando yarn en mi proyecto de reacción. Dentro de mi archivo index.js en /scr y según los documentos web3, probé ambos (no al mismo tiempo)

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

y

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

antes de agregar

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

y termino con un error quejándose "No se puede leer la propiedad 0 de indefinido", lo que me lleva a pensar que el problema es con las cuentas [0].

De manera confusa, cuando se eliminan mis declaraciones de solicitud/importación en la parte superior de la página y se actualiza la página, el navegador detecta la metamáscara e imprime mi dirección en la consola. Además, recibo quejas de que mi objeto web3 no está definido, pero eso es de esperar.

No ejecuté explícitamente webpack o browserify porque webpack está incluido en los proyectos de reacción. ¿Es esto algo que necesito hacer?

¿Qué está pasando aquí y cómo puedo hacer que mi proyecto React funcione con metamask?

Respuestas (3)

Suena confuso y, según la versión de web3 que tenga, la sintaxis es diferente. Según el error que obtuviste en primer lugar, parece que estás usando web3 1.0. Sin embargo, el código de instancia es para la versión 0.2.xx

Solo para aclarar, así es como se verá su código en caso de que esté usando web3 1.0

importar Web3 desde 'web3';

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

Básicamente, crea una instancia de web3 con givenProvider(en caso de que esté usando metamask o mist) o con local. Luego obtienes tus cuentas .

En caso de que esté utilizando la versión anterior de web3, el código es ligeramente diferente:

importar Web3 desde 'web3';

dejar web3 = nulo;
if (tipo de web3 !== 'indefinido') {
  web3 = new Web3(web3.currentProvider);
} más {
  // establezca el proveedor que desea de Web3.providers
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

web3.eth.getAccounts(devolución de llamada(error, resultado){ console.log(resultado) })
¡Gracias! Pensé que estaba usando la versión anterior porque 1.0 todavía está en versión beta, pero yarn add web3 instaló automáticamente 1.0

La forma más sencilla es usar el componente react-web3-provider .

Agregue el Web3Providercomponente React a su raíz:

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

Luego, en el componente donde desea usar 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);

A partir de julio de 2019, su mejor oportunidad es web3-react . Eche un vistazo a cómo se usa en Uniswap .

Vistazo:

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