Я пишу этот компонент списка продуктов и борюсь с государствами.Каждый продукт в списке является самим компонентом.Все отображается так, как предполагалось, за исключением того, что компонент не обновляется при смене реквизита.Я использую рекомпозицию withPropsOnChange()
, надеясь, что она будет срабатывать при каждом изменении реквизита в shouldMapOrKeys
.Однако этого никогда не происходит.
Позвольте мне показать код:
import React from 'react'
import classNames from 'classnames'
import { compose, withPropsOnChange, withHandlers } from 'recompose'
import { addToCart } from 'utils/cart'
const Product = (props) => {
const {
product,
currentProducts,
setProducts,
addedToCart,
addToCart,
} = props
const classes = classNames({
addedToCart: addedToCart,
})
return (
<div className={ classes }>
{ product.name }
<span>$ { product.price }/yr</span>
{ addedToCart ?
<strong>Added to cart</strong> :
<a onClick={ addToCart }>Add to cart</a> }
</div>
)
}
export default compose(
withPropsOnChange([
'product',
'currentProducts',
], (props) => {
const {
product,
currentProducts,
} = props
return Object.assign({
addedToCart: currentProducts.indexOf(product.id) !== -1,
}, props)
}),
withHandlers({
addToCart: ({
product,
setProducts,
currentProducts,
addedToCart,
}) => {
return () => {
if (addedToCart) {
return
}
addToCart(product.id).then((success) => {
if (success) {
currentProducts.push(product.id)
setProducts(currentProducts)
}
})
}
},
}),
)(Product)
Не думаю, что это уместно, но функция addToCart
возвращает Promise.Прямо сейчас оно всегда разрешается в true
.
Еще одно уточнение: currentProducts
и setProducts
являются соответственно атрибутом и методом из класса (модели), который содержит данные корзины.Это также хорошо работает, не выдает исключений и не показывает неожиданное поведение.
Здесь предполагается следующее: при добавлении товара в корзину и после обновления списка currentProducts
пропеллер addedToCart
изменит свое значение.,Я могу подтвердить, что currentProducts
обновляется как ожидалось.Однако эта часть кода не достигнута (я добавил точку останова в эту строку):
return Object.assign({
addedToCart: currentProducts.indexOf(product.id) !== -1,
}, props)
Поскольку я уже использовал подобную структуру для другого компонента - основное отличие тамв том, что один из реквизитов, которые я «слушаю», определяется withState()
- мне интересно, чего мне здесь не хватает.Моей первой мыслью было, что проблема была вызвана прямым обновлением currentProducts
, здесь:
currentProducts.push(product.id)
Поэтому я попробовал другой подход:
const products = [ product.id ].concat(currentProducts)
setProducts(products)
Это не изменилосьхоть что-нибудь во время выполнения.
Я подумываю использовать withState
вместо withPropsOnChange
.Я думаю, это будет работать.Но прежде чем идти по этому пути, я хотел знать, что я здесь делаю неправильно.