Ei pessoal, bom dia. Alguém já precisou atualizar tanto o contexto de product
, quanto o contexto de product-summary
da PLP (vtex.search
)? Se sim, como consigo fazer isso?
Contexto da pergunta
-
Estou usando os dispatches
SET_PRODUCT
que estão disponíveis emvtex.product-context
evtex.product-summary-context
. -
No ProductContextProvider, existe um
useEffect
chamadouseSelectedItemFromId
que roda sempre queproduct
ouquery
muda. -
Esse effect
useSelectedItemFromId
procura o SKU dequery
dentro desseproduct
, e chama umSET_SELECTED_PRODUCT
. Caso nenhum SKU seja encontrado,selectedProduct
ficaundefined
e todos os componentes que usam esse atributo param de funcionar corretamente (add-to-cart-button
,sku-selector
, etc). -
O contexto de produto é criado através de um produto que vêm como prop, que é recuperado através de uma chamada de GraphQL. Esse produto é então copiado para um estado interno do provider, este que temos acesso e conseguimos alterar quando usamos um
useProduct
ouuseProductDispatch
. -
O problema é que, o
useEffect
ali de cima é chamado apenas quando oproduct
ou
query
que vêm de fora mudam. Por algum motivo que não consegui identificar, oSET_PRODUCT
doproductSummaryDispatch
muda a variávelquery
para um SKU do produto que acabei de selecionar. Isso triggasetSelectedItemFromId
, mas como oproduct
não está sincronizado com o valor do estado interno, ele não encontra o SKU em questão eselectedItem
vai para null.
Não consegui entender porque nem onde query
muda, e não consegui encontrar qual componente que cria esse product-context ao redor do product-summary. Alguém já passou por isso?
Código que estou usando
O código que estou usando, que adaptei do código encontrado em
vtex.product-summary-context
:
function useSetProduct() {
const productSummaryDispatch = useProductSummaryDispatch()
const productDispatch = useProductDispatch()
return (
product: ProductSummaryTypes.Product,
{ replaceURL = false } = {}
) => {
// Get first available SKU
// If there is no SKU available, returns the first one
const firstAvailableSKU =
product?.items?.find((d) => {
const seller = getDefaultSeller(d.sellers)
return (seller?.commertialOffer?.[PROTERTY_AVAILABLE_QUANTITY] ?? 0) > 0
}) || product?.items?.[0]
/*
* For some reason, the product within productSummaryContext has some extra properties,
* such as an SKU attribute. This seems to be set by ProductSummarySKUSelector during initialization
* and it's likely to be deprecated in the future, as the comment bellow suggests:
*
* "//TODO: STOP USING PRODUCT.SKU https://app.clubhouse.io/vtex/story/18547/productsummarycontext-refactor"
*
* ProductSummaryContext.tsx
* https://github.com/vtex-apps/product-summary-context/blob/master/react/ProductSummaryContext.tsx#L81
*
* ProductSummarySKUSelector.tsx
* https://github.com/vtex-apps/product-summary/blob/1d908de85f310541f058e0449a2aa553b8a1f783/react/ProductSummarySKUSelector.tsx#L189
*/
const sku = {
...firstAvailableSKU,
image: firstAvailableSKU.images[0],
seller: getDefaultSeller(
firstAvailableSKU.sellers
) as ProductSummaryTypes.Seller,
}
const newProduct = {
...product,
selectedItem: firstAvailableSKU,
sku,
}
productSummaryDispatch?.({
type: 'SET_PRODUCT',
args: { product: newProduct },
})
productDispatch?.({
type: 'SET_PRODUCT',
args: { product: (product as unknown) as ProductTypes.Product },
})
productDispatch?.({
type: 'SET_SELECTED_ITEM',
args: { item: (firstAvailableSKU as unknown) as ProductTypes.Item },
})
}
}