在Context生成需要await的合约,拿到的是null

一开始在context里面是这样写的

ts 复制代码
  
  const [reporterToken, setReporterToken] = useState(null);
  //...
  
  let reporterTokenTemp;

  const generateReporterToken = async () => {
    try {
      const reportertoken_addr = await token.getConditionalTokens();

      reporterTokenTemp = new ethers.Contract(
        reportertoken_addr,
        new Interface(conditionalToken_abi),
        provider.getSigner()
      );

      setReporterToken(reporterTokenTemp);
    } catch (error) {
      console.error("generateReporterToken error", error);
    }
  };

  useEffect(() => {
    if (token?.provider) {
      generateReporterToken();
    }
  }, [token?.provider]);

  return (
    <Web3Context.Provider
      value={{
        contracts: {
        //..
          reporterToken: reporterToken,
        },
      
      }}
    >
      {children}
    </Web3Context.Provider>
  );

然后在要用到reporterToken合约的地方用useWeb3Context去拿到reporterToken的时候一开始总是拿到null,这是因为const [reporterToken, setReporterToken] = useState(null); 的初始值是null 等reporterToken合约生成好后,context不会实时更新。所以我尝试了:

尝试1:给reporterToken单独生成一个context ,因为reporterToken是依赖token合约的,所以新的context得在Web3Context下面,才能拿到token合约

尝试2:因为context不能实时更新数据,就用useDispatch去更新,但是因为在按原本的代码,生成合约是在异步函数里面,不能调用useDispatch

javascript 复制代码
const generateReporterToken = async () => {
//不能在这里调用hook 
}

如果把函数改成自定义hook:

ts 复制代码
const useReporterToken = async ({ token, provider }) => {
  const reportertoken_addr = await token.getConditionalTokens();
  let reporterToken = new ethers.Contract(
    reportertoken_addr,
    new Interface(conditionalToken_abi),
    provider.getSigner()
  );
    useDispatch({reporterToken};//那就可以用useDispatch
};

但是既然改成自定义hook,为什么不直接拿到返回值呢

ts 复制代码
const useReporterToken = async ({ token, provider }) => {
  const reportertoken_addr = await token.getConditionalTokens();
  let reporterToken = new ethers.Contract(
    reportertoken_addr,
    new Interface(conditionalToken_abi),
    provider.getSigner()
  );
  return reporterToken;
};

这样子在使用的时候 又得包裹一层async await

所以最终的解决方案是在使用到reporterToken 合约的地方直接生成,当然也可以采用尝试1,但是那样代码量会多一些

ts 复制代码
useEffect(() => {
    (async () => {
      try {
       //直接生成合约
        const reportertoken_addr = await token.getConditionalTokens();
        let reporterToken = new ethers.Contract(
          reportertoken_addr,
          new Interface(conditionalToken_abi),
          provider.getSigner()
        );
        //使用到reporterToken 合约的地方:
        let conditionID = await reporterToken?.getConditionId(
        //..
相关推荐
搬砖的码农20 分钟前
(08)为什么我的 Agent 一跑后台服务就卡死
前端·agent·ai编程
飘尘22 分钟前
前端转全栈(Java 后端)必须要知道的:开发中的锁机制与分布式并发控制
前端·后端·全栈
亲亲小宝宝鸭29 分钟前
前端性能监控:web-vitals
前端·性能优化·监控
陆枫Larry1 小时前
可滚动页面背景填不满:`height: 100vh` vs `min-height: 100vh`
前端
Patrick_Wilson1 小时前
Squash Merge 的血缘陷阱:为什么删掉的代码又活了过来
前端·git·程序员
kyriewen2 小时前
今天的科技圈,全在抢英伟达的饭碗
前端·面试·ai编程
SouthernWind2 小时前
RAGFlow——结合本地知识库检索开发实战指南(包含聊天、检索本地的知识库文档和Agent模式)
前端
三翼鸟数字化技术团队2 小时前
websocket及SSE原理解析
前端
妙码生花3 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(八):设计管理员模型、热重载配置
前端·后端·go