重新加载 Commerce.js 结帐页面时出错(反应教程)
Getting error when reloading the Commerce.js Checkout page (react tutorial)
我目前正在为 Commerce.js Api.React.js 结帐教程。
当我点击购物车中的结账按钮时,它会将我带到结账页面并按预期生成结账令牌,但我注意到当我重新加载结账页面时控制台显示以下错误:
Image of errors.
这是结帐页面的代码:
import React, { useEffect, useState } from 'react';
import { commerce } from '../../lib/commerce';
import './styles.css';
const Checkout = ({ cart }) => {
const [checkoutToken, setCheckoutToken] = useState({});
useEffect(() => {
generateCheckoutToken();
}, [])
const generateCheckoutToken = () => {
if (cart.line_items.length) {
commerce.checkout.generateToken(cart.id, { type: 'cart' })
.then((token) => {
setCheckoutToken(token);
console.log(checkoutToken);
}).catch((error) => {
console.log('There was an error in generating a token', error);
});
}
}
return (
<div>
Checkout
</div>
)
}
export default Checkout
我认为这与使用 generateCheckoutToken()
功能之前购物车未加载有关,但我不明白如何解决该问题。
这里是 App.js:
import { useEffect, useState } from 'react';
import { commerce } from './lib/commerce';
import { Routes, Route } from 'react-router-dom';
import ProductsList from './components/ProductList/ProductsList';
import Cart from './components/Cart/Cart';
import Checkout from './components/Checkout/Checkout';
import './App.css';
function App() {
const [products, setProducts] = useState([]);
const [cart, setCart] = useState({});
const [prductLoading, setProductLoading] = useState(false);
const [cartBtn, setCartBtn] = useState(false);
const fetchProducts = () => {
commerce.products.list().then((products) => {
setProducts(products.data);
setProductLoading(false);
}).catch((error) => {
console.log('There was an error fetching the products', error);
});
}
const fetchCart = () => {
commerce.cart.retrieve().then((cart) => {
setCart(cart)
}).catch((error) => {
console.error('There was an error fetching the cart', error);
});
}
const handleAddToCart = (productId, quantity) => {
commerce.cart.add(productId, quantity).then((item) => {
setCart(item.cart)
}).catch((error) => {
console.error('There was an error adding the item to the cart', error);
});
}
const handleUpdateCartQty = (lineItemId, quantity) => {
commerce.cart.update(lineItemId, { quantity }).then((resp) => {
setCart(resp.cart)
}).catch((error) => {
console.log('There was an error updating the cart items', error);
});
}
const handleRemoveFromCart = (lineItemId) => {
commerce.cart.remove(lineItemId).then((resp) => {
setCart(resp.cart)
}).catch((error) => {
console.error('There was an error removing the item from the cart', error);
});
}
const handleEmptyCart = () => {
commerce.cart.empty().then((resp) => {
setCart(resp.cart)
}).catch((error) => {
console.error('There was an error emptying the cart', error);
});
}
const handleCloseCart = () => {
setCartBtn(false);
}
useEffect(() => {
setProductLoading(true);
fetchProducts();
fetchCart();
}, [])
// console.log(cart);
return (
<div className="App">
<Routes>
<Route
exact
path='/'
element={
<div className='home'>
<div className={`cart-button ${cartBtn && 'cartOpen'}`}>
{cartBtn ?
<Cart
cart={cart}
onUpdateCartQty={handleUpdateCartQty}
onRemoveFromCart={handleRemoveFromCart}
onEmptyCart={handleEmptyCart}
closeCartBtn={handleCloseCart}
/>
:
<p onClick={() => setCartBtn(true)}>Open cart</p>
}
</div>
{prductLoading ?
'Loading...'
:
<ProductsList
products={products}
onAddToCart={handleAddToCart}
/>
}
</div>
}
/>
<Route
exact
path='/checkout'
element={
<Checkout
cart={cart}
/>
}
/>
</Routes>
</div>
);
}
export default App;
如果有人能告诉我我缺少什么,我将不胜感激,感谢您的帮助!!
问题
当你在App
状态下初始化cart
时,它是一个空对象{}
。这是作为道具传递给 Checkout
.
一旦 Checkout
安装,它就会调用 generateCheckoutToken
,它会尝试读取 cart.line_items.length
。如果这发生在父对象调用 fetchCart
之前,则 cart
是一个没有 line_items
的空对象。这是一个竞争条件。
一个解决方案
一个解决方案是监听 cart
在 useEffect
中的变化,并且只在 cart
有 line_items
时调用 generateCheckoutToken
。这可能不支持您未来的设计目标,但它应该可以解决此错误。
// Checkout
useEffect(() => {
if(cart.line_items) {
generateCheckoutToken();
}
}, [cart])
我目前正在为 Commerce.js Api.React.js 结帐教程。
当我点击购物车中的结账按钮时,它会将我带到结账页面并按预期生成结账令牌,但我注意到当我重新加载结账页面时控制台显示以下错误: Image of errors.
这是结帐页面的代码:
import React, { useEffect, useState } from 'react';
import { commerce } from '../../lib/commerce';
import './styles.css';
const Checkout = ({ cart }) => {
const [checkoutToken, setCheckoutToken] = useState({});
useEffect(() => {
generateCheckoutToken();
}, [])
const generateCheckoutToken = () => {
if (cart.line_items.length) {
commerce.checkout.generateToken(cart.id, { type: 'cart' })
.then((token) => {
setCheckoutToken(token);
console.log(checkoutToken);
}).catch((error) => {
console.log('There was an error in generating a token', error);
});
}
}
return (
<div>
Checkout
</div>
)
}
export default Checkout
我认为这与使用 generateCheckoutToken()
功能之前购物车未加载有关,但我不明白如何解决该问题。
这里是 App.js:
import { useEffect, useState } from 'react';
import { commerce } from './lib/commerce';
import { Routes, Route } from 'react-router-dom';
import ProductsList from './components/ProductList/ProductsList';
import Cart from './components/Cart/Cart';
import Checkout from './components/Checkout/Checkout';
import './App.css';
function App() {
const [products, setProducts] = useState([]);
const [cart, setCart] = useState({});
const [prductLoading, setProductLoading] = useState(false);
const [cartBtn, setCartBtn] = useState(false);
const fetchProducts = () => {
commerce.products.list().then((products) => {
setProducts(products.data);
setProductLoading(false);
}).catch((error) => {
console.log('There was an error fetching the products', error);
});
}
const fetchCart = () => {
commerce.cart.retrieve().then((cart) => {
setCart(cart)
}).catch((error) => {
console.error('There was an error fetching the cart', error);
});
}
const handleAddToCart = (productId, quantity) => {
commerce.cart.add(productId, quantity).then((item) => {
setCart(item.cart)
}).catch((error) => {
console.error('There was an error adding the item to the cart', error);
});
}
const handleUpdateCartQty = (lineItemId, quantity) => {
commerce.cart.update(lineItemId, { quantity }).then((resp) => {
setCart(resp.cart)
}).catch((error) => {
console.log('There was an error updating the cart items', error);
});
}
const handleRemoveFromCart = (lineItemId) => {
commerce.cart.remove(lineItemId).then((resp) => {
setCart(resp.cart)
}).catch((error) => {
console.error('There was an error removing the item from the cart', error);
});
}
const handleEmptyCart = () => {
commerce.cart.empty().then((resp) => {
setCart(resp.cart)
}).catch((error) => {
console.error('There was an error emptying the cart', error);
});
}
const handleCloseCart = () => {
setCartBtn(false);
}
useEffect(() => {
setProductLoading(true);
fetchProducts();
fetchCart();
}, [])
// console.log(cart);
return (
<div className="App">
<Routes>
<Route
exact
path='/'
element={
<div className='home'>
<div className={`cart-button ${cartBtn && 'cartOpen'}`}>
{cartBtn ?
<Cart
cart={cart}
onUpdateCartQty={handleUpdateCartQty}
onRemoveFromCart={handleRemoveFromCart}
onEmptyCart={handleEmptyCart}
closeCartBtn={handleCloseCart}
/>
:
<p onClick={() => setCartBtn(true)}>Open cart</p>
}
</div>
{prductLoading ?
'Loading...'
:
<ProductsList
products={products}
onAddToCart={handleAddToCart}
/>
}
</div>
}
/>
<Route
exact
path='/checkout'
element={
<Checkout
cart={cart}
/>
}
/>
</Routes>
</div>
);
}
export default App;
如果有人能告诉我我缺少什么,我将不胜感激,感谢您的帮助!!
问题
当你在App
状态下初始化cart
时,它是一个空对象{}
。这是作为道具传递给 Checkout
.
一旦 Checkout
安装,它就会调用 generateCheckoutToken
,它会尝试读取 cart.line_items.length
。如果这发生在父对象调用 fetchCart
之前,则 cart
是一个没有 line_items
的空对象。这是一个竞争条件。
一个解决方案
一个解决方案是监听 cart
在 useEffect
中的变化,并且只在 cart
有 line_items
时调用 generateCheckoutToken
。这可能不支持您未来的设计目标,但它应该可以解决此错误。
// Checkout
useEffect(() => {
if(cart.line_items) {
generateCheckoutToken();
}
}, [cart])