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

如何在API调用完成返回结果后正确更新React State

问题原因

你拿不到接口返回值核心是三个问题,和useEffect、回调逻辑无关:

  • 前端signup函数没有返回axios发起请求的Promise实例:函数内没有写return语句,默认返回undefined,.then里的return只是回调函数的内部返回值,不会被外层signup函数抛出,所以await signup(...)会直接拿到undefined,不会等接口请求完成。
  • 后端FastAPI接口返回格式不规范:你用大括号包裹格式化后的字符串,实际返回的是Python单元素集合(set),序列化后会变成数组,前端需要取[0]才能拿到文案,而且你把哈希后的密码拼在返回文案里存在安全风险。
  • 表单提交逻辑缺e.preventDefault(),默认提交行为会触发页面跳转,也会导致状态更新异常。
修改代码

1. 修正前端signup请求函数

给axios请求加上return,保证Promise链能被await捕获,两种写法都可以:

// 写法1:保留原有then链式调用,补全return
function signup(name, email, password){
  return axios.post('/register', {
    username: name,
    email: email,
    password: password
  })
  .then(function (response) {
    return response.data;
  })
}

// 写法2:改成async/await,逻辑更直观,不容易漏return
async function signup(name, email, password) {
  const res = await axios.post('/register', {
    username: name,
    email: email,
    password: password
  })
  return res.data
}

2. 修正React组件提交逻辑

补全表单默认行为阻止、错误处理,拼接要求的文案前缀:

export default function Signup() {
  const [message, setMessage] = useState('Welcome')
  async function handleSubmit(e){
    // 阻止表单默认提交跳转
    e.preventDefault()
    try {
      const resText = await signup(
        usernameRef.current.value, 
        emailRef.current.value, 
        passwordRef.current.value
      )
      // 拼接要求的hello前缀
      setMessage(`hello ${resText}`)
    } catch (err) {
      setMessage('注册提交失败,请稍后重试')
    }
  }

  return(
    <div>
      <p>{message}</p>
      {/* 原有表单代码,提交事件绑定handleSubmit即可 */}
    </div>
  )
}

注:状态设置函数建议用小驼峰setMessage,符合React社区约定,大写开头的Setmessage虽然能运行,但可读性差。

3. 修正FastAPI后端返回逻辑

去掉包裹返回值的大括号,直接返回字符串,同时删掉文案里拼接的密码字段:

@app.post("/register")
async def user_register(user: UserIn_Pydantic):
    user_info = user.dict(exclude_unset=True)
    user_info["password"] = get_password_hash(user_info["password"])
    user_obj = await User.create(**user_info)
    new_user = await user_pydantic.from_tortoise_orm(user_obj)
    await simple_send(email=[new_user.email], instance=new_user)

    # 直接返回字符串,去掉外层大括号,移除密码字段
    return f"{new_user.username}, please check your email for verification"

改完之后提交表单就会等接口返回完整文案后,再更新页面显示的message内容,不会再出现undefined的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:42:29