【发布时间】:2016-07-21 08:03:48
【问题描述】:
我有一个表格,在编辑时显示有关票证的信息。票据是从 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);
}
【问题讨论】:
-
您传递给 SelectForm 的 onChange 事件是否没有保持其范围?也许尝试绑定它 - onChange={this.handleSelectChange.bind(this)}
-
@hootstheowl 事件工作正常,除了 setState 之后的数据以一种奇怪的方式处理。
-
"每当我从类型中选择一个选项时,它的状态就会改变,甚至无需触摸它,反之亦然。"这是什么意思。以及你想用
handleChange()实现什么 -
问题不在于
handleChange(),无论如何我正在监听子组件。问题出在handleSelectChange(),setState没有按预期工作。我必须独立更改每个字段,但它们以一种奇怪的方式相互交互。如果我更改一个字段,其他字段会自动更改,但这是不对的。
标签: javascript select reactjs onchange react-jsx