在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(
        //..
相关推荐
C_心欲无痕11 小时前
浏览器缓存: IndexDB
前端·数据库·缓存·oracle
郑州光合科技余经理11 小时前
技术架构:上门服务APP海外版源码部署
java·大数据·开发语言·前端·架构·uni-app·php
GIS之路11 小时前
GDAL 实现数据属性查询
前端
PBitW12 小时前
2025,菜鸟的「Vibe Coding」时刻
前端·年终总结
mwq3012312 小时前
不再混淆:导数 (Derivative) 与微分 (Differential) 的本质对决
前端
小二·13 小时前
Vue 3 组件通信全方案详解:Props/Emit、provide/inject、事件总线替代与组合式函数封装
前端·javascript·vue.js
研☆香13 小时前
html框架页面介绍及制作
前端·html
be or not to be14 小时前
CSS 定位机制与图标字体
前端·css
DevUI团队14 小时前
🔥Angular高效开发秘籍:掌握这些新特性,项目交付速度翻倍
前端·typescript·angular.js
Moment14 小时前
如何在前端编辑器中实现像 Ctrl + Z 一样的撤销和重做
前端·javascript·面试