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

useSWRMutation的onSuccess回调中phoneNumber状态陈旧问题

问题描述

在onSuccess回调中执行console.log(phoneNumber)时,输出为空字符串而非正确值,phoneNumber处于陈旧状态。只有在编辑器修改内容触发应用重新渲染后,phoneNumber才会显示正确值。尝试用useCallback包裹onSuccess以获取最新phoneNumber,但问题依然存在。

相关代码:

const verifyPhoneNumber = async (url: string, { arg: phoneNumber }) => {
  try {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        phone_number: phoneNumber,
      }),
    });
    const json = await response.json();
    return json;
  } catch (e) {
    console.log(e);
  }
};

const SignUp = (props: Props) => {
  const navigation = useNavigation();

  const [phoneNumber, setPhoneNumber] = useState("");

  const url = "https://jsonplaceholder.typicode.com/posts/";

  const { trigger, isMutating } = useSWRMutation(url, verifyPhoneNumber, {
    onSuccess: () => {
      // 问题所在:phoneNumber为空字符串
      console.log(phoneNumber)
      navigation.navigate("VerifyCode", {
        phoneNumber: phoneNumber,
      });
    },
    onError: (error) => console.log(error),
  });

  const sendOTP = () => {
    trigger(phoneNumber);
  };

  return (
    <AppBox>
      <InputFieldForAuth
        inputIsInvalid={false}
        value={phoneNumber}
        onChangeText={(newText: string) => setPhoneNumber(newText)}
        placeholder={`Enter your phone number here`}
      />
      <Button
        text="Continue"
        onPress={sendOTP}
      />
    </AppBox>
  );
};

尝试过的无效方案:

const onSuccess = useCallback(() => {
  console.log(phoneNumber);
  navigation.navigate("VerifyCode", {
    phoneNumber: phoneNumber,
  });
}, [phoneNumber]);

const { trigger, isMutating } = useSWRMutation(url, verifyPhoneNumber, {
  onSuccess: onSuccess,
  onError: (error) => console.log(error),
});
解决方案

直接利用useSWRMutation的onSuccess回调提供的参数,获取trigger时传入的最新phoneNumber,无需依赖组件状态,彻底避开闭包问题:

const { trigger, isMutating } = useSWRMutation(url, verifyPhoneNumber, {
  // 从回调参数中获取trigger时传入的arg值
  onSuccess: (data, { arg: latestPhoneNumber }) => {
    console.log(latestPhoneNumber); // 这里是最新的手机号
    navigation.navigate("VerifyCode", {
      phoneNumber: latestPhoneNumber,
    });
  },
  onError: (error) => console.log(error),
});
原理说明

useSWRMutation的trigger方法接收的参数(即这里的phoneNumber)会被SWR内部保存,并在onSuccess回调中通过第二个参数{ arg }返回。这种方式不需要依赖组件的state,完全避免了闭包捕获陈旧状态的问题,是最可靠的解决方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:55:28