React Commerce.js教程中结账页面刷新出现报错如何解决?
问题根源
- 你在App组件中将cart的初始值设为了空对象
{},刷新结账页时,Checkout组件挂载的时机远早于fetchCart接口返回购物车数据的时机,此时访问cart.line_items.length时line_items为undefined,直接读取length属性就会触发报错。 - Checkout组件中调用
generateCheckoutToken的useEffect依赖数组为空,仅会在组件首次挂载时执行一次,就算后续cart加载完成,也不会重新触发生成checkout token的逻辑。 - 额外小问题:你在
setCheckoutToken之后直接打印checkoutToken是拿不到最新值的,React的useState更新是异步的,同步代码执行时状态还没更新。
修复方案
1. 修改Checkout组件代码
修改后的完整代码如下:
import React, { useEffect, useState } from 'react'; import { commerce } from '../../lib/commerce'; import './styles.css'; const Checkout = ({ cart }) => { const [checkoutToken, setCheckoutToken] = useState(null); const [loading, setLoading] = useState(false); // 把cart加入依赖数组,cart加载完成后会重新执行 useEffect(() => { generateCheckoutToken(); }, [cart]) const generateCheckoutToken = () => { // 加可选链避免访问undefined的属性,同时如果已经生成过token就不再重复生成 if (!checkoutToken && cart?.line_items?.length) { setLoading(true); commerce.checkout.generateToken(cart.id, { type: 'cart' }) .then((token) => { setCheckoutToken(token); // 要打印最新token直接打返回的token对象 console.log(token); }).catch((error) => { console.log('There was an error in generating a token', error); }).finally(() => { setLoading(false); }); } } // 可以加加载状态提升体验 if (loading || !checkoutToken) return <div>加载中...</div> return ( <div> Checkout </div> ) } export default Checkout
2. 优化App组件(可选但建议)
- 你可以把cart的初始值改成
{ line_items: [] },从根源避免line_items为undefined的情况 - 注意你的代码里有拼写错误:
prductLoading应该是productLoading,可以修正避免后续出问题 - 如果想要更好的体验,可以给购物车也加一个加载状态,在购物车未加载完成时,结账页显示加载占位。
内容的提问来源于stack exchange,提问作者Knee-co
相关产品推荐
相关产品推荐

