我正在尝试使用ReactJS构建一个动态组件。因此,我有一个产品列表,每次用户想要添加新产品时,他都会单击+按钮。这将创建一个新产品并将其添加到列表中。该列表有一个名为Delete All的按钮,用于删除所有产品。
要删除所有产品,我在组件创建时使用了产品列表中初始化为“Created”的状态,当用户单击“Delete All”时,我将其更改为“Delete”,并使用ComponentWillUpdate回调更新Childs(产品)。
以下是一些代码:
Index.js
render() {
return (
<div className="App">
<h1>Dynamic List</h1>
<ProductList />
<hr />
<h1>Static List</h1>
<ProductListStatic />
</div>
);
}
Product.js
class Product extends React.Component {
constructor(props) {
super(props);
this.state = {
state: "created"
};
}
componentDidUpdate(prevProps) {
if (
this.props.parentState === "deleted" &&
this.state.state === "created"
) {
this.setState({ state: "deleted" });
}
}
render() {
if (this.state.state !== "deleted") {
return (
<div style={{ margin: "5px" }}>
Product.....
<button onClick={this.props.addNewProduct}>+</button>
</div>
);
} else {
return null;
}
}
}
我的ProductList.js
class ProductList extends React.Component {
constructor(props) {
super(props);
this.state = {
products: [],
state: "created"
};
}
componentDidMount() {
let newProducts = [...this.state.products];
newProducts.push(
<Product
key={0}
addNewProduct={this.addNewProduct}
parentState={this.state.state}
/>
);
this.setState({ products: newProducts });
}
addNewProduct = () => {
let length = this.state.products.length;
const newProducts = [
...this.state.products,
<Product
key={length}
addNewProduct={this.addNewProduct}
parentState={this.state.state}
/>
];
this.setState({ products: newProducts });
};
deleteAll = () => {
this.setState({ state: "deleted" });
};
render() {
return (
<div>
{this.state.products}
<button style={{ marginTop: "20px" }} onClick={this.deleteAll}>
Delete All
</button>
</div>
);
}
}
好吧,这并没有更新蔡尔兹夫妇,我不知道为什么。我认为这是因为这份名单是动态的。我尝试了一下使用静态列表,它运行得很好(代码如下)。
ProductListStatic.js
class ProductListStatic extends React.Component {
constructor(props) {
super(props);
this.state = {
products: [],
state: "created"
};
}
deleteAll = () => {
console.log("delete all");
this.setState({ state: "deleted" });
};
render() {
let products = [
<Product
key={0}
addNewProduct={this.addNewProduct}
parentState={this.state.state}
/>,
<Product
key={1}
addNewProduct={this.addNewProduct}
parentState={this.state.state}
/>
];
return (
<div>
{products}
<button style={{ marginTop: "20px" }} onClick={this.deleteAll}>
Delete All
</button>
</div>
);
}
}
以下是一个演示:SandBox live dome
有人知道为什么它不适用于动态产品吗?
1条答案
按热度按时间iszxjhcz1#
问题是状态数组中的JSX元素不知道在父数组重新呈现时需要重新呈现它们。在静态版本中,子对象是直接在JSX中创建的,因此重新渲染的行为是正常的。将子对象的data存储在状态数组中,然后在每次呈现时通过在该状态数组上调用
.map
来创建它们是一个合理的解决方案。除此之外,总体设计似乎不必要地复杂。我不认为子对象
Product
应该关心它们何时呈现,或者是否应该通过子对象的回调将产品添加到父对象中。将所有这些信息保存在家长中要简单得多。呈现可以是隐式的--如果我们想要一个新项目,将它推到产品/项目数组上,如果我们想清除所有项目,则将数组设置为[]
。不需要this.state.state
。这里有一个概念验证:
如果您计划为每个产品添加其他按钮和数据,则可以使用行容器。然后,当更改应该应用于项时,行将需要回调来通知父级。这取决于您的设计目标,在这一点上还为时过早(在从
Product
中消除了渲染方面的顾虑之后,就没有多少东西可以证明它的存在了)。