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

React调用useState更新状态后Apollo查询仍使用旧状态如何解决?

问题根源

存在两个核心错误导致请求携带旧值:

  • React的useState返回的更新方法setStatus是异步批量执行的,调用后不会立刻修改当前作用域下的status变量值,同一个函数执行上下文里拿到的还是调用setStatus之前的旧状态值
  • 按钮的onClick绑定错误:代码中写的是onClick={handleSubmit()},相当于组件渲染时就会立即执行handleSubmit,而不是点击按钮时才触发
  • 补充:你提供的GraphQL mutation语法存在错误,updateData payload: $data) 少了左括号,修复后应为updateData(payload: $data)
修复方案

方案1:直接使用常量传参(最简洁,适配当前场景)

你不需要依赖state的值来传参,直接把要更新的状态定义为常量,同时给state赋值和传给mutation即可:

import React,{useState} from "react";
import { gql, useMutation } from '@apollo/client';
import Button from "@material-ui/core/Button";

const UPDATE_DATA = gql`
mutation updateData( $data: UpdateDataInput!){
    updateData(payload: $data)
  }`

export default function StatusPage() {

 const [updateData] = useMutation(UPDATE_DATA);
 const [status,setStatus] = useState("OLD");
  const handleSubmit = async () => {
    // 定义目标状态常量
    const targetStatus = "NEW";
    setStatus(targetStatus)
    try {
      const result = await updateData({
        variables: {
          data: {
            status: targetStatus // 直接用常量传参,不需要从state取
          }
        }
      });
      if(result.data) {
        console.log("SUCCESS")
      }
    } catch (e) {
      console.log("ERROR")
    }
  };
  return (
      {/* 去掉handleSubmit后面的括号,实现点击才触发逻辑 */}
      <Button type ="submit" onClick={handleSubmit}> Submit </Button>
  );
}

方案2:用useEffect监听state变化触发请求(适配逻辑复杂、必须依赖最新state的场景)

如果后续你的逻辑里status更新可能来自多个地方,必须等state更新后再发请求,可以用useEffect监听status变化:

import React,{useState, useEffect} from "react";
import { gql, useMutation } from '@apollo/client';
import Button from "@material-ui/core/Button";

const UPDATE_DATA = gql`
mutation updateData( $data: UpdateDataInput!){
    updateData(payload: $data)
  }`

export default function StatusPage() {

 const [updateData] = useMutation(UPDATE_DATA);
 const [status,setStatus] = useState("OLD");
 const [shouldSubmit, setShouldSubmit] = useState(false);

 // 监听提交标记和status变化,状态更新后再发起请求
 useEffect(() => {
  if(shouldSubmit && status === "NEW") {
    const submitRequest = async () => {
      try {
        const result = await updateData({
          variables: {
            data: {
              status: status
            }
          }
        });
        if(result.data) {
          console.log("SUCCESS")
        }
      } catch (e) {
        console.log("ERROR")
      } finally {
        setShouldSubmit(false)
      }
    }
    submitRequest();
  }
 }, [status, shouldSubmit, updateData])

 const handleSubmit = () => {
  setShouldSubmit(true);
  setStatus("NEW");
 };

  return (
      <Button type ="submit" onClick={handleSubmit}> Submit </Button>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:45:01