#javascript #reactjs #e-commerce #commerce #commerce.js
Вопрос:
В настоящее время я занимаюсь React.js учебник по оформлению заказа для Commerce.js Api.
Когда я нажимаю кнопку «Оформить заказ» в корзине, она выводит меня на страницу оформления заказа и генерирует маркер оформления заказа, как и должно быть, но я заметил, что при перезагрузке страницы оформления заказа консоль показывает следующие ошибки: Изображение ошибок.
А это код для страницы оформления заказа:
import React, { useEffect, useState } from 'react'; import { commerce } from '../../lib/commerce'; import './styles.css'; const Checkout = ({ cart }) =gt; { const [checkoutToken, setCheckoutToken] = useState({}); useEffect(() =gt; { generateCheckoutToken(); }, []) const generateCheckoutToken = () =gt; { if (cart.line_items.length) { commerce.checkout.generateToken(cart.id, { type: 'cart' }) .then((token) =gt; { setCheckoutToken(token); console.log(checkoutToken); }).catch((error) =gt; { console.log('There was an error in generating a token', error); }); } } return ( lt;divgt; Checkout lt;/divgt; ) } 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 = () =gt; { commerce.products.list().then((products) =gt; { setProducts(products.data); setProductLoading(false); }).catch((error) =gt; { console.log('There was an error fetching the products', error); }); } const fetchCart = () =gt; { commerce.cart.retrieve().then((cart) =gt; { setCart(cart) }).catch((error) =gt; { console.error('There was an error fetching the cart', error); }); } const handleAddToCart = (productId, quantity) =gt; { commerce.cart.add(productId, quantity).then((item) =gt; { setCart(item.cart) }).catch((error) =gt; { console.error('There was an error adding the item to the cart', error); }); } const handleUpdateCartQty = (lineItemId, quantity) =gt; { commerce.cart.update(lineItemId, { quantity }).then((resp) =gt; { setCart(resp.cart) }).catch((error) =gt; { console.log('There was an error updating the cart items', error); }); } const handleRemoveFromCart = (lineItemId) =gt; { commerce.cart.remove(lineItemId).then((resp) =gt; { setCart(resp.cart) }).catch((error) =gt; { console.error('There was an error removing the item from the cart', error); }); } const handleEmptyCart = () =gt; { commerce.cart.empty().then((resp) =gt; { setCart(resp.cart) }).catch((error) =gt; { console.error('There was an error emptying the cart', error); }); } const handleCloseCart = () =gt; { setCartBtn(false); } useEffect(() =gt; { setProductLoading(true); fetchProducts(); fetchCart(); }, []) // console.log(cart); return ( lt;div className="App"gt; lt;Routesgt; lt;Route exact path='/' element={ lt;div className='home'gt; lt;div className={`cart-button ${cartBtn amp;amp; 'cartOpen'}`}gt; {cartBtn ? lt;Cart cart={cart} onUpdateCartQty={handleUpdateCartQty} onRemoveFromCart={handleRemoveFromCart} onEmptyCart={handleEmptyCart} closeCartBtn={handleCloseCart} /gt; : lt;p onClick={() =gt; setCartBtn(true)}gt;Open cartlt;/pgt; } lt;/divgt; {prductLoading ? 'Loading...' : lt;ProductsList products={products} onAddToCart={handleAddToCart} /gt; } lt;/divgt; } /gt; lt;Route exact path='/checkout' element={ lt;Checkout cart={cart} /gt; } /gt; lt;/Routesgt; lt;/divgt; ); } export default App;
Я был бы признателен, если бы кто-нибудь мог сказать мне, чего мне не хватает, спасибо за вашу помощь!!
Комментарии:
1.
cart.line_items is undefined
-gt; gt;cart
происходит отprops
. Как это определено в родителе?2. обновил вопрос
Ответ №1:
Вопрос
При инициализации cart
в App
состоянии это пустой объект {}
. Это передается как опора для Checkout
.
Как только Checkout
монтируется, он звонит generateCheckoutToken
, который пытается прочитать cart.line_items.length
. Если это происходит до fetchCart
того, как вызывается в родительском объекте, cart
это пустой объект, который не line_items
нужно учитывать. Это условие гонки.
Одно из решений
Одним из решений было бы прислушаться cart
к изменениям в useEffect
, и звонить только generateCheckoutToken
тогда, когда cart
это произойдет line_items
. Это может не соответствовать вашим будущим целям проектирования, но должно устранить эту ошибку.
// Checkout useEffect(() =gt; { if(cart.line_items) { generateCheckoutToken(); } }, [cart])