【问题标题】:How to use variables from outside of a react component如何使用来自反应组件外部的变量
【发布时间】:2022-01-07 00:38:25
【问题描述】:

我的 react 组件外部有一个 async 函数,它从 2 个地址检索 2 个令牌余额。我想在注释掉的 HTML 行中渲染出 2 个地址的余额。特别是linkBalancebalanceuseContext 钩子我想也许我可以使用 context 解决我的问题,但我不确定。

import { ethers } from 'ethers'
const { ethereum } = window


const provider = new ethers.providers.Web3Provider(window.ethereum);
const linkAddress = '0xa36085F69e2889c224210F603D836748e7dC0088'
const linkABI = require('../constants/erc20.json')
const linkContract = new ethers.Contract(linkAddress, linkABI, provider);

(async() => {
    const accounts = await ethereum.request({ method: 'eth_accounts' })
    const account = accounts[0]
    const balance = await provider.getBalance(account)
    console.log(ethers.utils.formatUnits(balance, 18))
    const linkBalance = await linkContract.balanceOf(contractAddress)
    console.log(ethers.utils.formatUnits(linkBalance, 18))
})()


const Main = () => {

    const { connectWallet, currentAccount } = useContext(PackPlayersContext)

    return(
        <>
            <div>
                {currentAccount && (<p>Current Address: {currentAccount}</p>)}
                {!currentAccount && (
                    <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={connectWallet}>Connect Wallet</button>
                )}

                <input className="shadow appearance-none border rounded w-half py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="username" type="text" placeholder="Price"/>
                <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mb-4 mt-4">Buy Pack</button>

            {/* 
            <div>
                <p>Current link balance of contract: {linkBalance}</p>
                <p>Your KETH balance: {balance}</p>
            </div>
            */}
            </div>
        </>
    )
}
export default Main

【问题讨论】:

  • 为什么异步函数必须在反应组件之外?
  • 您可以将数据作为props 传递到组件中,也可以使用redux 之类的东西来处理数据存储。
  • 为什么要在组件之外设置异步函数?我假设您想在渲染组件之前运行您的函数,如果是这种情况,您应该使用 useEffect 钩子来执行此操作。
  • 你可以像这样作弊和定义变量,window.newvariable = "hello";并且所有函数都可以在最高级别看到这个范围。
  • 我似乎已经解决了这个问题,看看下面,我不确定我是否以最有效的方式做到了。

标签: javascript reactjs ethers.js


【解决方案1】:

我胜利归来了。

我创建了一个单独的文件来放置我的异步函数,并将其用作上下文提供程序,在该上下文提供程序中,我更新了一个保存我的代币余额的状态。然后我将其作为上下文传递给我的 html。

这是上下文文件

import React, { useState, useEffect} from 'react'
import { contractAddress } from '../constants/constants'
import { ethers } from 'ethers'
const { ethereum } = window

export const BalancesContext = React.createContext()

const provider = new ethers.providers.Web3Provider(window.ethereum);
const linkAddress = '0xa36085F69e2889c224210F603D836748e7dC0088'
const linkABI = require('../constants/erc20.json')
const linkContract = new ethers.Contract(linkAddress, linkABI, provider);


export const BalancesProvider = ({ children }) => {
    const[currentLinkBalance, setCurrentLinkBalance] = useState()
    const[currentKethBalance, setCurrentKethBalance] = useState()

    const getBalances = async () => {
        const accounts = await ethereum.request({ method: 'eth_accounts' })
        const account = accounts[0]
        const balance = await provider.getBalance(account)
        console.log(ethers.utils.formatUnits(balance, 18))
        setCurrentKethBalance(ethers.utils.formatUnits(balance, 18))
        const linkBalance = await linkContract.balanceOf(contractAddress)
        console.log(ethers.utils.formatUnits(linkBalance, 18))
        setCurrentLinkBalance(ethers.utils.formatUnits(linkBalance, 18))
    }

    useEffect(() => {
        getBalances()
    }, [])

    return (
        <BalancesContext.Provider value ={{ currentLinkBalance, currentKethBalance }}>
            {children}
        </BalancesContext.Provider>
    )
}

这是新的主要组件

import { PackPlayersContext } from "../context/PackPlayersContext"
import React, { useContext, useState } from 'react'
import { BalancesContext } from "../context/BalancesContext"

const Main = () => {
    const { connectWallet, currentAccount } = useContext(PackPlayersContext)
    const { currentLinkBalance, currentKethBalance } = useContext(BalancesContext)

    return(
        <>
            <div>
                {currentAccount && (<p>Current Address: {currentAccount}</p>)}
                {!currentAccount && (
                    <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={connectWallet}>Connect Wallet</button>
                )}

                <input className="shadow appearance-none border rounded w-half py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="username" type="text" placeholder="Price"/>
                <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mb-4 mt-4">Buy Pack</button>
            <div>
                <p>Current link balance of contract: {currentLinkBalance}</p>
                <p>Your KETH balance: {currentKethBalance}</p>
            </div>
            </div>
        </>
    )
}
export default Main

感谢大家的帮助和建议。最后,我是 react 和 js 的新手,所以老实说,我不知道这是否是一种愚蠢的做法,但它可以正常工作。但是,我总是乐于学习最佳实践,所以如果有任何错误或愚蠢的做法,请发表评论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-06
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2019-07-19
    • 2015-04-23
    • 2021-11-14
    相关资源
    最近更新 更多