当我通过子组件使用addQuantityButton
函数将新产品添加到产品数组时,在子产品组件中无法识别对产品数组的更改。父组件中的addQuantityButton
函数正在向数组中正确添加新对象。当我开始使用Redux和mapStateToProps时,它停止工作。我在这里做什么错了?
路径:Parent
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
products: [getNewProduct()]
};
this.addQuantityButton = this.addQuantityButton.bind(this);
}
addQuantityButton(product_id) {
let { products } = this.state;
products = products.map((product) => {
if (product.product_id === product_id) {
product.quantities.push(getNewQuantity());
return product;
}
return product;
});
this.setState({
products
});
}
render() {
const { products } = this.state;
return (
<form>
{products.map((product) => (
<Product
key={product.key}
product_id={product.product_id}
quantities={product.quantities}
addQuantityButton={this.addQuantityButton}
/>
))}
</form>
);
}
}
路径:Product
class Product extends React.Component {
constructor(props) {
super(props);
this.state = {
unitOptions: []
};
}
render() {
return (
<div>
<div>
{this.props.quantities.map((quantity) => (
<p>Example</p>
))}
</div>
<button
type="button"
onClick={() => addQuantityButton(this.props.product_id)}
>
Add quanity
</button>
</div>
);
}
}
Product.propTypes = {
product_id: PropTypes.string,
quantities: PropTypes.array,
addQuantityButton: PropTypes.func
};
const mapStateToProps = (state) => ({
supplierProducts: state.product.products
});
export default connect(mapStateToProps)(Product);
答案 0 :(得分:2)
孩子正在侦听redux的状态,这不同于父状态。 react component状态是一回事,redux状态是另一回事。建议不要将redux的状态复制到组件的状态。
我建议父母在这里仅将您的产品映射到道具,然后以this.props.products.map(...
的形式迭代您的表单
在“儿童”中,您声明mapDispatchToProps
负责增加数量。在那里您声明了addQuantityButton
并进行了一些重构。您将改用调度来接收操作。添加产品的逻辑将在您的减速器中实现。
const mapDispatchToProps = (dispatch, ownProps) => ({
addQuantityButton: dispatch(addQuantity(ownProps.product_id))
})
您的动作是在某些动作文件中声明的简单函数,该函数返回一个包含动作类型和有效负载的对象(您可以将有效负载称为“ fwiw”):
const addQuantity = product_id => ({
type: 'ADD_QUANTITY',
payload: product_id
})
现在,以适当的动作进行分派会将对象向下传递给减速器,并且拦截ADD_QUANTITY
的给定减速器将负责增加数量,并以此方式返回下一个Redux状态。
在reducer上,您实现了更新状态的逻辑。
function productsReducer(state = initialState, action) {
switch (action.type) {
case 'ADD_QUANTITY': // suggestion, declare your types as a constant in another file
// also, dont mutate state directly!, you may need to use some deep clone given it's an array of objects
return // logic here with action.payload and state.products
default:
return state
}
}