我正在编写此产品列表组件,并且正在与状态作斗争。列表中的每个产品本身就是一个组件。一切都按预期呈现,除了当道具更改时组件没有更新。我正在使用 recompose,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
. 我想那会奏效。但在这样做之前,我想知道我在这里做错了什么。