我有一个表格,在编辑时显示有关票证的信息。票证作为对象从 API 接收,在我的例子中是 data
(例如 apiUrl: {tickets: '/api/tickets'}
)。 data
包含工单的所有默认状态,例如:优先级、状态和类型。所有API数据都在TicketForm
中管理成分。参见下面的组件代码:
class TicketForm extends Component {
constructor(props) {
super(props);
this.handleSelectChange = this.handleSelectChange.bind(this);
this.save = this.save.bind(this);
this.state = {
apiUrl: {tickets: '/api/tickets'},
data: {
id: '',
ticket: '',
key: '',
priority: {
id: "",
name: ""
},
status: {
id: "",
name: ""
},
type: {
id: "",
name: ""
}
},
priority: [],
status: [],
type: []
};
}
componentWillMount() {
//Getting the JSON from APIs
}
save() {
//Saving/Updating data to server
}
handleSelectChange(e) {
for (var i = 0; i < this.state[e.target.name].length; i++) {
if (this.state[e.target.name][i].id == e.target.value) {
this.state.data[e.target.name] = this.state[e.target.name][i];
}
}
this.setState({data: this.state.data});
}
render() {
return (
<table className="table table-striped">
<tbody>
<tr>
<th>Priority:</th>
<td>
<SelectForm
onChange={this.handleSelectChange}
name="priority"
options={this.state.priority}
selected={this.state.data.priority.name}/>
</td>
</tr>
<tr>
<th>Status:</th>
<td>
<SelectForm
onChange={this.handleSelectChange}
name="status" options={this.state.type}
selected={this.state.data.type.name}/>
</td>
</tr>
<tr>
<th>Type:</th>
<td>
<SelectForm
onChange={this.handleSelectChange}
name="type"
options={this.state.status}
selected={this.state.data.status.name}/>
</td>
</tr>
</tbody>
</table>
)
}
}
我想在单击元素时编辑此信息,然后渲染 <select>
包含从 API 作为数组接收的一些选项,以及可应用于字段的不同选项:优先级、状态和类型。这是一个与上面不同的 API(例如 apiUrl: {tickets: '/api/tickets/type'}
)。选择option
后,我从所选对象中获取数据并将其替换为初始 data
目的。请参阅SelectForm
组件如下:
export default class SelectForm extends Component {
constructor(props) {
super(props);
this.state = {
edit: false
};
}
editProject() {
this.setState({edit: true});
}
blurProject() {
this.setState({edit: false});
}
handleChange(e) {
if (this.props.onChange) {
this.props.onChange(e);
}
}
renderForm() {
return (
<select
className="form-control"
name={this.props.name}
onChange={this.handleChange.bind(this)}
onBlur={this.blurProject.bind(this)}>
{(Array.isArray(this.props.options) && this.props.options.length > 0) ? this.props.options.map(option => {
return (
<option key={option.id} value={option.id}>{option.name}</option>
)
}) : (<option>No Options Found</option>)}
</select>
)
}
render() {
if (this.state.edit) {
return this.renderForm();
} else {
return (
<p onClick={this.editProject.bind(this)}>{this.props.selected}</p>
)
}
}
}
我正在尝试处理更改事件。当从选择中选择其他选项时,根据所选选项设置状态,并在选择该选项后在字段中显示新状态。
我以为我已经实现了这一目标,但不知何故,它们之间的场表现得很奇怪。优先级似乎工作得很好,但每当我从类型中选择一个选项时,它的状态就会改变,甚至无需触摸它,反之亦然。
我无法理解问题所在,请查看handleSelectChange()
函数逻辑,并告诉我做错了什么,或者这个问题的一些解决方案。
更新:
在答案中发现,该文档关于 Immutability Helpers会有帮助的。我尝试使用链接中的一个示例,但得到了相同的结果。请看一下代码并让我知道我做得是否正确:
handleSelectChange(e) {
for (var i = 0; i < this.state[e.target.name].length; i++) {
if (this.state[e.target.name][i].id == e.target.value) {
var newState = update(this.state, {
data: {
[e.target.name]: { $set: this.state[e.target.name][i] }
}
});
}
}
this.setState(newState);
}
最佳答案
您需要使用immutable helpers或者像这样创建新对象:
this.setState(Object.assign({}, this.state, newState))
UPD: 尝试做这样的事情:
handleSelectChange(e) {
const data = Object.assign({}, this.state.data)
data[e.target.name] = e.target.value;
for (var i = 0; i < data[e.target.name].length; i++) {
if (data[e.target.name][i].id == e.target.value) {
data[e.target.name] = data[e.target.name][i];
}
}
this.setState({ data });
}
关于javascript - React 中 <select> 时 onChange 事件无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38498417/