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

React ContextAPI变量首次点击无法获取最新值问题求解

问题原因
  1. 登录按钮的点击回调中没有调用signIn异步方法,首次点击时未触发接口请求,Context中的count状态还是初始的undefined,判断count > 1自然不成立。
  2. React的状态更新是异步的,setCount执行后不会立刻修改当前闭包内的count值,只有等组件重新渲染后才能拿到更新后的状态。就算你在点击回调中调用了signIn,同一个回调内立刻读取count拿到的还是更新前的旧值,所以第一次点击判断不生效,第二次点击时count已经完成更新,才能拿到正确值。
  3. 原有逻辑错误:点击回调中不管count判断结果如何,都会直接执行Router.push("/dashboard"),会导致选择企业的逻辑还没执行就跳转页面。
解决方法

方案1:直接使用接口返回值判断(推荐)

不需要依赖状态判断,直接在signIn方法中返回接口拿到的企业数量,点击回调中await调用后直接用返回值处理逻辑:

修改AuthContext.ts中的signIn方法

async function signIn({ cpf, password, empresa }: SignInCredentials) {
  // 修正原笔误:password赋值错写为cpf
  setUser({
    cpf: cpf,
    password: password
  })

  if (!empresa) {
    const response: ResponseProps = await api.post('/session', {
      LOGIN: cpf,
      SENHA: password
    })
    const empresas = response.data.payload;
    setEmpresas(empresas);
    setCount(empresas.length)
    // 返回企业数量给调用方
    return empresas.length
  }

  if (empresa) {
    const response: ResponseUserProps = await api.post('/session', {
      LOGIN: cpf,
      SENHA: password,
      EMPRESA: empresa
    })
    const { token } = response.data.payload;

    setCookie(undefined, '@allNube.token', token, {
      maxAge: 60 * 60 * 24, // 24小时
    })
    api.defaults.headers['Authorization'] = `Bearer ${token}`;

    Router.push('/dashboard')
    return 0
  }
}

修改登录组件逻辑

export function Login() {
  const { signIn, empresas } = useContext(AuthContext);
  // 假设你已经在组件内维护了表单的cpf、password状态
  const [cpf, setCpf] = useState('')
  const [password, setPassword] = useState('')

  return (
    <Button
      onClick={async () => {
        // 先调用登录接口获取企业数量
        const companyCount = await signIn({cpf, password})
        if (companyCount > 1) {
          onSelectCompanyDrawer();
        } else if(companyCount === 1) {
          // 只有1家企业时直接调用登录完成跳转
          await signIn({cpf, password, empresa: empresas[0].CODIGO})
        }
      }}
      w="200px"
      h="48px"
      mb="4"
      type="submit"
    >
      Acessar
    </Button>
  );
}

方案2:用useEffect监听count变化

如果需要依赖Context的count状态做逻辑,可以通过useEffect监听count变化,状态更新后自动触发对应逻辑:

export function Login() {
  const { signIn, count, empresas } = useContext(AuthContext);
  const [cpf, setCpf] = useState('')
  const [password, setPassword] = useState('')

  // count更新后自动执行判断
  useEffect(() => {
    if(!count) return
    if(count > 1) {
      onSelectCompanyDrawer();
    } else if(count === 1) {
      signIn({cpf, password, empresa: empresas[0].CODIGO})
    }
  }, [count, cpf, password, empresas, signIn])

  return (
    <Button
      onClick={() => signIn({cpf, password})}
      w="200px"
      h="48px"
      mb="4"
      type="submit"
    >
      Acessar
    </Button>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:45:00