在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(
        //..
相关推荐
深念Y1 小时前
Lenovo XiaoXinAir 14 — 性能模式切换
前端·网络
计算机魔术师1 小时前
Meta突然杀进第一梯队:一个新模型,把AI推理成本打下来8倍
前端
IT_陈寒2 小时前
Redis缓存雪崩把我坑惨了,这次长记性了
前端·人工智能·后端
风骏时光牛马2 小时前
提示词工程:大模型效能挖掘与指令设计实战
前端
仓三2 小时前
Chrome DevTools MCP 上手:让 Coding Agent 自己调试前端页面
前端·chrome devtools·mcp
计算机魔术师2 小时前
扒完Google AI Agent挑战赛的前三名,我发现了一个共同点
前端
不可能片场2 小时前
resources/app 为何能覆盖 app.asar
前端·electron
小婉2 小时前
我用 Next.js + React Flow 从零搭建了一个可视化 AI 工作流编排平台
前端·人工智能·node.js
skiyee2 小时前
🚀 用 17 行代码给 UniApp 加上全局登录拦截
前端·uni-app