NextJS中如何让useSWR仅在页面加载时调用一次API?
问题:Next.js中使用useSWR获取Stripe Payment Intent重复请求的解决办法
我正在NextJS中自定义Stripe支付表单,需要创建Payment Intent并调用API获取client secret。使用useSWR和axios实现时,当前配置会重复请求API,希望页面加载时仅调用一次API。
我的代码如下:
const BillingPage = () => { const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY); const {data: intent, error, mutate} = useSWR('/api/stripe-intent', () => axios.get('/api/stripe-intent') .then(response => response.data) ) if (! intent) { return (<LoadPageComponent />) } const options = { clientSecret: intent?.client_secret, } return ( <> <p>Payment form here</p> </> ) }
解决方法
方法1:调整useSWR的重验证配置
useSWR默认会在页面聚焦、重新连接网络或数据过时时自动重验证请求,通过关闭这些特性可以实现仅首次加载时请求一次:
const {data: intent, error, mutate} = useSWR('/api/stripe-intent', () => axios.get('/api/stripe-intent') .then(response => response.data), { revalidateIfStale: false, revalidateOnFocus: false, revalidateOnReconnect: false } )
revalidateIfStale: 设为false,避免数据过时时自动重请求revalidateOnFocus: 设为false,避免页面重新聚焦时重请求revalidateOnReconnect: 设为false,避免网络重新连接时重请求
这种方式保留了useSWR的缓存能力,后续如果需要手动刷新数据,依然可以调用mutate()方法。
方法2:改用useEffect实现单次请求
如果不需要useSWR的缓存、重新验证等特性,直接用useEffect配合useState也能实现页面挂载时仅请求一次:
const BillingPage = () => { const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY); const [intent, setIntent] = useState(null); const [error, setError] = useState(null); useEffect(() => { const fetchPaymentIntent = async () => { try { const response = await axios.get('/api/stripe-intent'); setIntent(response.data); } catch (err) { setError(err); } }; fetchPaymentIntent(); }, []); // 空依赖数组确保仅组件挂载时执行一次 if (! intent) { return (<LoadPageComponent />) } const options = { clientSecret: intent?.client_secret, } return ( <> <p>Payment form here</p> </> ) }
内容的提问来源于stack exchange,提问作者BigJobbies
相关产品推荐
相关产品推荐

