Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/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
Javascript 简单的添加/删除组件模式_Javascript_Design Patterns_Reactjs - Fatal编程技术网

Javascript 简单的添加/删除组件模式

Javascript 简单的添加/删除组件模式,javascript,design-patterns,reactjs,Javascript,Design Patterns,Reactjs,我对React中的这种模式很困惑。我在其他地方见过,但似乎不正确 鉴于以下代码: /** @jsx React.DOM */ var React = window.React = require('react'), Item = require("./ui/Item"); var ItemApp = React.createClass({ getInitialState: function() { return { items: [ "Example Item

我对React中的这种模式很困惑。我在其他地方见过,但似乎不正确

鉴于以下代码:

/** @jsx React.DOM */

var React = window.React = require('react'),
    Item = require("./ui/Item");

var ItemApp = React.createClass({
  getInitialState: function() {
    return {
      items: [ "Example Item" ] // we want one thing to render initially
    };                          // so prepopulate with one thing
  },
  getDefaultProps: function () {
    return {
      index: 1
    }
  },
  onAddItem: function (e) {
    var debts = this.state.debts.push( "New Item " + this.props.index);
    this.setState({ items: this.state.items });
    this.props.index++;
  },
  onRemoveItem: function (i) {
    // splice here
    this.state.items.splice(i, 1);
    this.setState({ items: this.state.items });
    this.props.index--;
  },
  render: function () {
    var items = this.state.items;
    var closeFn = this.onRemoveItem;
    return (
      <div className="col-lg-12">
        <div className="cold-md-3"></div>
        <div className="col-md-3 col-md-offset-9">
          <button type="button" className="btn btn-default" onClick={this.onAddItem}><span className="glyphicon glyphicon-plus"></span> Add New Debt</button>
        </div>
        {items.map(function (item, i) {
          return <Item name={item} closeFn={closeFn.bind(null, i)} key={i} />;
        })}
      </div>
    );
  }
});
/**@jsx React.DOM*/
var React=window.React=require('React'),
项目=要求(“/ui/项目”);
var ItemApp=React.createClass({
getInitialState:函数(){
返回{
items:[“Example Item”]//我们希望最初呈现一个东西
};//所以用一件事预先填充
},
getDefaultProps:函数(){
返回{
索引:1
}
},
onAddItem:函数(e){
var债务=this.state.debtes.push(“新项目”+this.props.index);
this.setState({items:this.state.items});
this.props.index++;
},
onRemoveItem:函数(i){
//在这里拼接
本.状态.项目.拼接(i,1);
this.setState({items:this.state.items});
这个.props.index--;
},
渲染:函数(){
var items=this.state.items;
var closeFn=this.onremovietem;
返回(
增加新债务
{items.map(函数(item,i){
返回;
})}
);
}
});
上面的例子就像预期的一样(它是一个列表,你可以随意添加和删除东西),但是每当我添加一些东西时,就会重新渲染整个事情

因此,在只添加了一个组件之后,整个组件已经渲染了3次。单击两次后,它将渲染5次。你可以看到为什么这可能是一个问题


这似乎真的很低效,有没有更好的方法呢?

如果您想手动管理dom,react可能不适合您。如果你真的愿意,你总是可以做得比抽象更好

在react中,通常最好的目标是代码能够清楚地表达其反应意图,并让它做自己的事情

如果代码很接近,唯一的问题是
属性不能唯一地反映数组中的项。当您有一个堆栈时,基于索引的键是100%可用的。我回答了一个类似的问题

要真正解决这个问题,因为任何项目都可以随时删除,所以需要在项目本身中编码一个唯一的标识符。与存储字符串数组不同,您应该存储对象数组
[{id:'1',text:'a},{id:'2',text:'b},{id:'3',text:'c}]
。然后,您可以使用id作为密钥,这样会更有效


这与问题无关,但是
This.props.index--
正在修改道具,这是不好的和不可靠的。如果出于某种原因需要保留计数器,请直接在componentWillMount中的
this
上设置它。如果需要在树上进行通信,可以接受回调作为支持,并调用它


另外,
没有说明从项目中获取数据的任何方法,请求删除时除外。

我建议不要使用
this.state.items.splice(I,1)-状态的直接突变是一种不好的做法
this.setState()
在您修改状态后立即开始状态转换查看组件多次渲染的更多方式。每次调用组件上的setState(),组件都将重新渲染。状态已更改,因为存在不同的项。为什么不重新渲染以显示组件的更新状态?我只是认为它将附加一个新的而不是删除其中的内容并渲染两个新的。如果您关心性能,我建议阅读React的diffing算法的工作原理。我发现React的性能相当好。是的,在原始帖子中设置关键点的方式导致对象被不必要地重新渲染。由于键是基于索引的,因此当删除对象时,可能会有很大一部分元素(取决于删除的索引)具有新键,并且必须重新渲染,因为react认为这些项已更改。