在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(
        //..
相关推荐
荣达2 小时前
koa洋葱模型理解
前端·后端·node.js
reembarkation3 小时前
使用pdfjs-dist 预览pdf,并添加文本层的实现
前端·javascript·pdf
KenXu3 小时前
F2C-PTD工具将需求快速转换为代码实践
前端
给月亮点灯|3 小时前
Vue3基础知识-setup()、ref()和reactive()
前端·javascript·vue.js
芜青3 小时前
【Vue2手录12】单文件组件SFC
前端·javascript·vue.js
冷冷的菜哥3 小时前
react实现无缝轮播组件
前端·react.js·typescript·前端框架·无缝轮播
hrrrrb3 小时前
【Python】字符串
java·前端·python
阿笑带你学前端3 小时前
Supabase云同步架构:Flutter应用的数据同步策略
前端
梦想CAD控件3 小时前
(在线CAD平台)网页集成CAD SDK的方法
前端·javascript·github
万少3 小时前
可可图片编辑 HarmonyOS(6)水印效果
前端·harmonyos