Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ReactJs儿童没有';父状态更改后无法更新_Reactjs_Jsx - Fatal编程技术网

ReactJs儿童没有';父状态更改后无法更新

ReactJs儿童没有';父状态更改后无法更新,reactjs,jsx,Reactjs,Jsx,我正在尝试使用ReactJS构建一个动态组件。因此,我有一个产品列表,每次用户想要添加新产品时,他都会单击+按钮。这将创建一个新产品并将其添加到列表中。列表中有一个名为delete all的按钮,用于删除所有产品 要删除所有产品,我在组件创建时使用了产品列表中以“created”初始化的状态,当用户单击delete all时,我将其更改为“deleted”,以使用ComponentWillUpdate回调更新孩子(产品) 下面是一些代码: index.js render() { retu

我正在尝试使用ReactJS构建一个动态组件。因此,我有一个产品列表,每次用户想要添加新产品时,他都会单击+按钮。这将创建一个新产品并将其添加到列表中。列表中有一个名为delete all的按钮,用于删除所有产品

要删除所有产品,我在组件创建时使用了产品列表中以“created”初始化的状态,当用户单击delete all时,我将其更改为“deleted”,以使用ComponentWillUpdate回调更新孩子(产品)

下面是一些代码:

index.js

render() {
    return (
      <div className="App">
        <h1>Dynamic List</h1>
        <ProductList />
        <hr />
        <h1>Static List</h1>
        <ProductListStatic />
      </div>
    );
  }
render(){
返回(
动态列表

静态列表 ); }
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;
    }
  }
}
类产品扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
状态:“已创建”
};
}
componentDidUpdate(prevProps){
如果(
this.props.parentState==“已删除”&&
this.state.state==“已创建”
) {
this.setState({state:“deleted”});
}
}
render(){
如果(this.state.state!=“已删除”){
返回(
产品。。。。。
+
);
}否则{
返回null;
}
}
}
my 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>
    );
  }
}
类ProductList扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
产品:[],
状态:“已创建”
};
}
componentDidMount(){
让newProducts=[…this.state.products];
新产品(
);
this.setState({products:newProducts});
}
addNewProduct=()=>{
设长度=this.state.products.length;
常数新产品=[
…这个州的产品,
];
this.setState({products:newProducts});
};
deleteAll=()=>{
this.setState({state:“deleted”});
};
render(){
返回(
{this.state.products}
全部删除
);
}
}
这不会更新孩子们,我也不知道为什么。我想这是因为列表是动态的。我尝试使用一个静态列表,效果很好(代码如下)

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>
    );
  }
}
类ProductListStatic扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
产品:[],
状态:“已创建”
};
}
deleteAll=()=>{
控制台日志(“全部删除”);
this.setState({state:“deleted”});
};
render(){
让产品=[
,
];
返回(
{产品}
全部删除
);
}
}
下面是一个演示:


anynoe知道为什么它不适用于动态产品吗?

问题是状态数组中的JSX元素不知道在父元素重新渲染时需要重新渲染它们。在静态版本中,子对象直接在JSX中创建,因此重新渲染的行为是正常的。将子对象的数据存储在状态数组中,然后在每次渲染时在该状态数组上调用
.map
来创建它们,这是一个合理的解决方案

除此之外,总体设计似乎不必要地复杂。我不认为child
Product
s应该关心它们何时呈现,或者是否应该在父级中添加一个产品,并从子级回调。将所有这些信息保存在父级中要简单得多。呈现可以是隐式的——如果我们想要一个新项目,请将其推送到产品/项目数组中,如果我们想要清除所有项目,请将数组设置为
[]
。不需要
此.state.state

以下是概念证明:

const mockProduct=()=>({
姓名:[
“苹果”、“香蕉”、“樱桃”、“猕猴桃”,
“西瓜”、“菠萝”、“蓝莓”
][~~(Math.random()*7)],
价格:~~(Math.random()*5)+0.99
});
const Product=props=>
{props.name}
{props.price}
;
类产品扩展了React.Component{
建造师(道具){
超级(道具);
this.state={products:[mockProduct()]};
this.addNewProduct=this.addNewProduct.bind(this);
this.deleteAll=this.deleteAll.bind(this);
}
addNewProduct(){
this.setState(state=>({
产品:state.products.concat(mockProduct())
}));
}
deleteAll(){
this.setState({products:[]});
}
render(){
返回(
{this.state.products.map((e,i)=>
+
)}
全部删除
);
}
}
render(,document.body)


您能在问题中发布相关代码吗?沙箱可能会随着时间的推移而改变或下降,使问题对未来的访问者毫无用处。您也需要删除产品,单独设置状态并不能真正起作用。setState({state:“deleted”,products:[]);有一件事,在代码沙箱中,您混合了UI状态管理(应该只关注数据类型(如对象、数字、布尔值等)在呈现JSX时。不要将JSX置于UI状态。UI状态应该只包含可序列化的数据类型,原因有很多,包括React的工作方式。因此,在渲染函数中,映射状态以返回JSX,并且无论在何处调用setState,都要确保其数据类型是poc的JavaScriptHnx ggorien的本机数据类型。如您所说如果我们想全部删除,则不需要childs state。但是,我想为这些childs添加一个state(产品名称和价格)在列表“全部发送”中添加一个新按钮。当用户单击它时,它会在每个子项上触发sendToServer函数以保存产品。在这种情况下,我不知道如何更改我的设计以使用您的设计?我仍然会在父项中添加“全部发送”按钮,因此我认为此示例仍然与该设计相关。它与“全部删除”相同除了代替(或补充)c之外