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
相关产品推荐
相关产品推荐

