如何删除特定的子 React 组件
How do I delete specific child React components?
JSFiddle: https://jsfiddle.net/morahood/cp569zg6/38/
当我从ServiceList
组件中删除子ServiceItem
组件时,我遇到了一个问题,即列表中的最后一个ServiceItem
被删除而不是目标ServiceItem
。上面的 JSFiddle 链接将有助于理解该问题,只需确保在输入字段中输入一些可识别信息,以便查看已删除的内容。
如何修复我的应用程序以删除相应的组件?
var ServiceForm = React.createClass({
render: function() {
return (
<form onSubmit={ this.handleFormSubmission } >
{ this.renderServiceItemList() }
<div className="btn btn-default btn-sm" onClick={ this.addServiceItem }>+ Append New Service Item</div>
<button type="submit" className="btn btn-success btn-lg pull-right">Submit</button>
</form>
);
},
getInitialState: function() {
return ({
serviceItems: [this.renderServiceItem]
});
},
handleFormSubmission: function(event) {
event.preventDefault();
var data = this.refs.service_item_list.getAllServiceItems();
var json = {
"service_request" : {
"services" : data,
"additional_recipients" : 'test@example.com',
"comments" : 'Hello world!'
}
};
console.log(json);
},
addServiceItem: function(event) {
var copy = this.state.serviceItems.slice();
copy.push(this.renderServiceItem);
this.setState({
serviceItems: copy
});
},
renderServiceItem: function(item, i) {
return (
<ServiceItem removeServiceItem={ this.removeServiceItem } data={item} key={i} ref={"service_item_" + i} />
);
},
removeServiceItem: function(event) {
var index = parseInt(event.target.value, 10);
var copy = this.state.serviceItems.slice();
copy.splice(index, 1);
this.setState({
serviceItems: copy
});
},
renderServiceItemList: function() {
return (
<ServiceItemList serviceItems={ this.state.serviceItems }
renderServiceItem={ this.renderServiceItem }
removeServiceItem={ this.removeServiceItem }
ref="service_item_list" />
);
}
});
var ServiceItemList = React.createClass({
render: function() {
var content;
if (this.props.serviceItems.length < 1) {
content = <div className="empty-service-list">There are no service items, click on append new service item below!</div>;
} else {
content = this.props.serviceItems.map(this.props.renderServiceItem);
}
return (
<div>
{ content }
</div>
);
},
getAllServiceItems: function() {
var data = [];
for (var ref in this.refs) {
data.push(this.refs[ref].serializeItem());
}
var merged = [].concat.apply([], data);
return(merged);
}
});
var ServiceItem = React.createClass({
render: function() {
return (
<div className="row">
<div className="col-sm-3">
<div className="form-group service-item">
<label>Service Item </label>
<select multiple ref="service_types" className="form-control">
<option>Oil Change</option>
<option>Tire Rotation</option>
<option>New Wiper Blades</option>
</select>
</div>
</div>
<div className="col-sm-3">
<div className="form-group">
<label>Customer </label>
<select ref="customer" className="form-control">
<option>Troy</option>
<option>Dave</option>
<option>Brandon</option>
</select>
</div>
</div>
<div className="col-sm-3">
<div className="form-group">
<label>Manufacturer </label>
<div className="input-group">
<input ref="manufacturer" type="text" className="form-control" />
</div>
</div>
</div>
<div className="col-sm-3">
<div className="form-group">
<label>Model </label>
<div className="input-group">
<input ref="model" type="text" className="form-control" />
</div>
<a href="#" onClick={ this.props.removeServiceItem }>
<span aria-hidden="true" className="remove-fields" onClick={ this.props.removeServiceItem }>×</span>
</a>
</div>
</div>
</div>
);
},
getInitialState: function() {
return({
service_types: [],
customer: '',
manufacturer: '',
model: ''
});
},
serializeItem: function() {
var customer = this.refs.customer.value;
var manufacturer = this.refs.manufacturer.value;
var model = this.refs.model.value;
var selected = this.getSelectedServiceItems();
var services = this.getSelectedServiceItems().map(function(item) {
return (
{
"service" : {
"service_type" : item,
"customer" : customer,
"manufacturer" : manufacturer,
"model" : model
}
}
)
});
return(services);
},
getSelectedServiceItems: function() {
var select = this.refs.service_types;
var values = [].filter.call(select.options, function (o) {
return o.selected;
}).map(function (o) {
return o.value;
});
return(values);
}
});
ReactDOM.render(
<ServiceForm />,
document.getElementById('container')
);
您的问题出在您的key={i}
上。
React 列表要求项目的键对项目是唯一的,无论项目在列表中的位置如何。这允许 react 在更新时对列表进行智能管理。
React 不会正确呈现以下更新:
From: To:
name: key: name: key:
Bill 0 Bill 0
Charlie 1 Dave 1
Dave 2
因为 react 认为查理记录是不变的(因为键是不变的)。
我建议您从检索到的服务项目中输入某种 ID 作为密钥。
关于名称,例如
From: To:
name: key: name: key:
Bill Bill Bill Bill
Charlie Charlie Dave Dave
Dave Dave
在这种情况下,React 将正确呈现更新(因为键对于项目是唯一的)。
相关文章:
- React组件等待所需道具进行渲染
- React组件-设置页面标题
- 为react组件传递道具的最佳方式
- react组件中的绑定方法
- 加载服务器端渲染的React组件后执行脚本
- 如何基于依赖性导入React组件
- 可以't在我的React组件中加载图像
- jsx-React组件中的格式化编号
- 在进行服务器端渲染时,我可以向客户端发送React组件吗
- 使用jquery在react组件内部设置样式可以吗
- 为什么我不能将键映射到 React 组件上
- webpack样式加载器-在react组件上导入不同的样式,而无需重写
- 无法将react组件作为属性传递给另一个组件
- 继承React组件的正确方式
- 在JSX中围绕React组件封装高阶组件(HOC)
- 根据React组件的名称渲染该组件
- react组件的正确命名规范
- 在另一个文件夹中显示React组件
- AJAX 请求没有在我的 React 组件中设置 this.state.data
- 有没有一条清晰的路径,我可以实现一个在 ScalaJS + React 中广泛使用上下文的 React 组件