我想拥有一个包含产品列表和listItems列表的组件,该组件可呈现每个产品,但这给了我错误:
TypeError: Cannot read property 'products' of undefined
new ProductList
src/components/products/ProductList.js:11
这是我的代码:
import React, { Component } from "react";
import productData from "./model";
import Product from "./Product"
class ProductList extends Component {
constructor(props) {
super(props);
this.state = {
products: productData,
listItems: this.state.products.map(product => (
<Product key={product.name.toString()} product={product} />
))
};
}
addProduct = (product) => {
this.state.products.push(product);
this.setState({
products: this.state.products
});
};
render() {
return (
<div>
<ul>{this.state.listItems}</ul>
<button onClick={e => this.addProduct({name: "some product", price: 54})}>Add Product</button>
</div>
);
}
}
export default ProductList;
model.js:
interface Product {
name: string;
price: number;
}
let productData: Array<Product> = [
{ name: "Sledgehammer", price: 125.75 },
{ name: "Axe", price: 190.5 },
{ name: "Bandsaw", price: 562.13 },
{ name: "Chisel", price: 12.9 },
{ name: "Hacksaw", price: 18.45 }
];
export default productData
当我更改为:
listItems: this.products.map(product => (
<Product key={product.name.toString()} product={product} />
))
我得到:
TypeError: Cannot read property 'map' of undefined
我在做什么错了?
答案 0 :(得分:1)
我认为您要在初始化状态时映射productsData
而不是this.state
listItems: productsData.map(product => (
<Product key={product.name.toString()} product={product} />
))
您可能可以将listItem从状态中移出,只需在render方法中重新创建
render() {
const listItems = this.state.products.map(product => (
<Product key={product.name.toString()} product={product} />
))
return (
<div>
<ul>{listItems}</ul>
<button onClick={e => this.addProduct({name: "some product", price: 54})}>Add Product</button>
</div>
);
}
或在addProduct方法中重新计算listItems状态-
addProduct = (product) => {
const newProducts = this.state.products.concat(product)
this.setState({
products: newProducts,
listItems: newProducts.map(product => (
<Product key={product.name.toString()} product={product} />
))
});
};
答案 1 :(得分:0)
在第一段代码中,您具有:
this.state = {
products: productData,
listItems: this.state.products.map(product => (
<Product key={product.name.toString()} product={product} />
))
};
此时,this.state
是undefined
,并且正在分配值。后续的自引用调用this.state.products
试图在this.state
上找到产品属性undefined
。
在第二段代码中,您具有:
this.state = {
products: productData,
listItems: this.products.map(product => (
<Product key={product.name.toString()} product={product} />
))
};
对于this.products
,是对实例ProductList上的products属性的引用,该实例也不存在。
尝试这样的事情:
import React, { Component } from "react";
import productData from "./model";
import Product from "./Product";
class ProductList extends Component {
constructor(props) {
super(props);
this.state = {
products: productData
};
}
addProduct = product => {
const { products } = this.state;
this.setState({
products: [...products, product]
});
};
render() {
const { products } = this.state;
return (
<div>
<ul>
{products.map(product => (
<Product key={product.name.toString()} product={product} />
))}
</ul>
<button
onClick={e => this.addProduct({ name: "some product", price: 54 })}
>
Add Product
</button>
</div>
);
}
}
export default ProductList;
作为一般的经验法则,状态应包含视图的数据模型。我们生成的html,例如<Product />
,应该是状态和道具的结果,并且应该存在于render函数中。