You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

useEffect内执行setState后state返回undefined无法使用问题咨询

问题本质

  • useState初始化时没有赋值,首次渲染时tokens的默认值就是undefined
  • useEffect在组件首次挂载完成后才触发执行,内部的getSupportedTokens是异步接口请求,setTokens要等接口返回后才会执行触发重渲染,所以首次渲染周期内所有读取tokens的操作拿到的都是初始的undefined
  • 控制台打印对象能看到完整值是浏览器控制台的引用机制导致:打印时记录的是对象的引用,等你手动点开控制台展开对象时,接口已经请求完成、状态已经更新,所以展示的是最新值,如果你打印console.log(JSON.stringify(tokens))就能看到首次输出是undefined

修复方案

  1. 给useState设置合理的初始值,避免初始undefined
  2. 所有用到tokens的位置增加非空判断,比如可选链操作符,或者条件渲染
  3. 调整listAvailableTokens的定义顺序,避免函数提升导致的调用报错

修复后代码示例

function App() {
  // 给初始状态设为空对象,也可以根据实际业务需要设为[]或者null
  const [tokens, setTokens] = useState({});
  console.log(tokens)

  useEffect(() => {
    // 先定义listAvailableTokens,再在init里调用,避免函数表达式无提升导致的报错
    const listAvailableTokens = async () => {
      const result = await Moralis.Plugins.oneInch.getSupportedTokens({
        chain: "eth", // 要使用的区块链(eth/bsc/polygon)
      });
      const tokensObject = result.tokens;
      console.log(tokensObject)
      setTokens(tokensObject);
    };

    async function init() {
      await Moralis.initPlugins();
      await Moralis.enable();
      await listAvailableTokens();
    }

    init();
  }, []);

  // 其他组件用到tokens时加判断,示例:
  // return (
  //   <div>
  //     {Object.keys(tokens).length > 0 && <TokenList tokens={tokens} />}
  //   </div>
  // )
}

子组件使用注意

如果要把tokens传递给子组件使用,子组件内部读取属性时统一用可选链写法:tokens?.属性名,避免状态还没更新完成时报读取属性的错误。

内容的提问来源于stack exchange,提问作者JimJam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 02:15:01