1

我试图记住反应组件中的一些值,因为即使数据没有改变(并且不会改变),它也会重新渲染。使用 useEffect + useState 可以正确显示数据,但每次重新渲染组件时都会触发功能。目前我正在尝试实现 useMemo 钩子,但异步调用/承诺在渲染过程中没有解决,所以它甚至不加载数据。我将尝试提供最多的信息:

这是我的 AppRouter 组件,我创建合同并将其作为值传递给将在其他一些组件中使用的提供程序:

import { useWeb3React } from "@web3-react/core";
import React, { useEffect, useState } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";

import { AdminScreen } from "../components/admin/AdminScreen";
import { ContractsContext } from "../components/ContractsContext";
import { Navbar } from "../components/ui/Navbar";
import { getLibrary } from "../helpers/web3Getters";
import { useCreateContract, useGetLibrary } from "../hooks.js/contractsHooks";
import { createContract } from "../web3-utils/contractCreation";
import { MarketRoutes } from "./MarketRoutes";
import { PrivateRoute } from "./PrivateRoute";

export const AppRouter = () => {
  const context = useWeb3React();
  //console.log("[1] context in app router: ", context);

  const { contract: kolorTokenContract, loading: loadingContract } =
    useCreateContract(
      context,
      "0x9414f981a5B5ef2bE455f2427E2166c35e8989fB",
      "abis/KolorToken.json"
    );

  return (
    //<p>{loadingLibrary ? "library ready" : "loading library"}</p>

    <ContractsContext.Provider value={[kolorTokenContract]}>
      <BrowserRouter>
        <Navbar />
        {/* Set private route for Admining nfts & tokens */}
        <Routes>
          <Route
            path="/admin"
            element={
              <PrivateRoute>
                <AdminScreen />
              </PrivateRoute>
            }
          />

          <Route path="/*" element={<MarketRoutes />} />
        </Routes>
      </BrowserRouter>
    </ContractsContext.Provider>
  );
};

然后从我在管理路径中的自定义上下文中获取合同(这是我现在正在测试的),然后传递给它的一个孩子:

import React, { memo, useContext, useMemo } from "react";
import { getERC20Info } from "../../helpers/tokenGetters";
import { useGetERC20Info } from "../../hooks.js/contractsHooks";
import { ContractsContext } from "../ContractsContext";

export const TokenInfo = memo((tokenContract) => {
  //const { _address: ERC20Address } = tokenContract;
  const { address, owner, vault, supply } = useGetERC20Info(tokenContract);

  //const result = useMemo(() => getERC20Info(tokenContract), [tokenContract]);

  //console.log("contract from tokeninfo:", tokenContract);
  //console.log("result: ", result);

  return (
    <div className="row align-items-center">
      <div className="col-8 col-md-6 col-sm-4 ">Minting Form</div>
      <div className="col-4 col-md-3 col-sm-2 animate__animated animate__fadeInRightBig">
        <h2>Kolor Token Info</h2>
        <p>
          Address: <b>{address}</b>
        </p>
        <p>
          Owner: <b>{owner}</b>
        </p>
        <p>
          Vault: <b>{vault}</b>
        </p>
        <p>
          Current supply: <b>{supply}</b>
        </p>
      </div>

      <hr />
    </div>
  );
});

实际上,我正在使用带有 useState 和 useEffect 的自定义钩子来获取数据,但即使 tokenContract 根本没有改变,它也会重新呈现 TokenInfo 组件。这是我的自定义钩子:

export const useGetERC20Info = (contract) => {
  //console.log("contract from usegeterc20info effect: ", contract);

  const [state, setState] = useState({
    address: "loading...",
    owner: "loading...",
    vault: "loading...",
    supply: "loading",
  });

  useEffect(() => {
    getERC20Info(contract).then(({ address, owner, vault, supply }) => {
      setState({
        address,
        owner,
        vault,
        supply,
      });
      return () => {
        setState({});
      };
    });
  }, [contract]);

  return state;
};

我的 getERC20Info 函数,试图从区块链中获取数据,没有错,它工作正常:

export const getERC20Info = async (contract) => {
  console.log("getting erc20 info...");
  console.log("contract from geterc20info: ", contract);

  const { _address: address } = contract;
  const owner = await getERC20Owner(contract);
  const vault = await getERC20Vault(contract);
  const supply = await getERC20Supply(contract);

  //console.log("supply: ", supply);

  return {
    address,
    owner,
    vault,
    supply,
  };
};

提前感谢您的帮助!

4

0 回答 0