我对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>
);
}
});
上面的例子就像预期的那样(它是一个列表,你可以随意添加和删除东西)但是每当我添加一些东西时,整个事情都会重新呈现。
因此,在仅添加一个组件后,整个事件已呈现3次。点击两次后,它将渲染5次。你可以看出为什么这可能是一个问题。
这似乎真的效率低下是否有更好的方法来做到这一点?
答案 0 :(得分:2)
如果你想手动管理dom,反应可能不适合你。如果你真的想要,你总是可以比抽象更好。
作为反应,通常最好的目标是能够清楚地表达其反应意图的代码,并让它做到这一点。
您的代码已接近,唯一的问题是您的key
属性不能唯一地反映数组中的项目。当你有一个堆栈时,基于索引的键是100%罚款。我给了一个more detailed answer类似的问题。
要在此处实际解决此问题,因为任何项目都可以随时删除,您需要在项目本身中编码唯一标识符。您应该存储一个对象数组["a", "b", "c"]
,而不是存储字符串数组[{id: '1', text: "a"}, {id: '2', text: "b"}, {id: '3', text: "c"}]
。然后,您可以使用ID作为密钥,它会更有效。
这与问题无关,但是this.props.index--
正在修改道具,这是不好的和不可靠的。如果由于某种原因需要保留计数器,请直接在componentWillMount中的this
上设置。如果您需要在树上进行通信,则接受回调作为道具,然后调用它。
除了请求删除之外,<Item name={item} closeFn={closeFn.bind(null, i)} key={i} />
并没有描述从项目中取回数据的任何方法。