我正在学习ReactJS,并在管理我的对象状态时遇到了一些问题。我在下面描述了我想要做的和我采取的方法。如何管理ReactJS中JSON对象的某些属性的状态?
一般的想法是,我从REST服务接收到复杂的JSON对象。这个较大的JSON对象的属性之一是“保留”,它代表某天某个项目的预留。预留对象具有属性“项目”,“小时”(它们将被修改)和“availableProjects”列表。可用项目将通过下拉菜单显示,用户可以选择它来更新属性“reservation.project”。填充完所有预留,小时和其他一些属性后,我想将这个修改过的对象发送回服务器。
这里是代码:
var ReservationBox = React.createClass({
getInitialState: function() {
return {
reservation: this.props.reservation //IS THIS ANTI-PATTERN ?
}
},
onSelectProject: function (selectedProject) {
this.setState({reservation: {project: selectedProject}}); // IT WORKS but I don't know I did it correctly according to best practices :-)
},
handleHoursChange: function (e) {
this.setState({reservation: {hours: e.target.value}}) // THIS DOES NOT WORK
},
render: function() {
return (
<div>
{this.state.name}
<div className="btn-group timesheet-project-column">
<button type="button"
className="btn btn-primary">{this.state.reservation.project.projectName}</button>
<button type="button" className="btn btn-primary dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span className="caret"></span>
<span className="sr-only">Toggle Dropdown</span>
</button>
<AvailableProjectsListBox reservation={this.state.reservation}
onSelectProject={this.onSelectProject}/>
</div>
<div className="timesheet-column">
<button type="button" className="btn btn-default">
<span className="glyphicon glyphicon-pencil"/>
</button>
</div>
<div className="timesheet-column">
<input type="text" className="form-control timesheet-hour"
value={this.state.reservation.hours}
onChange={this.handleHoursChange}/>
</div>
<div className="timesheet-column">
<button type="button" className="btn btn-danger">
<span className="glyphicon glyphicon-trash img-circle text-danger"></span>
</button>
</div>
</div>
);
}
});
var AvailableProjectsListBox = React.createClass({
render: function() {
var onSelectProject = this.props.onSelectProject;
var availableProjects = this.props.reservation.availableProjects.map(function (availableProject) {
return (
<AvailableProject availableProject={availableProject}
onSelectProject={onSelectProject}/>
);
});
return (
<ul className="dropdown-menu">
{availableProjects}
</ul>
);
}
});
var AvailableProject = React.createClass({
handleSelectProject: function() {
this.props.onSelectProject(this.props.availableProject.project);
},
render: function() {
return (
<li><a href="#" onClick={this.handleSelectProject}>
{this.props.availableProject.project.projectName}</a>
</li>
);
}
});
我不能修改输入 “小时” - 它保持初始值。我的方法有什么问题?如何处理这种情况,我有大的JSON对象,其中许多部分不会被修改(所以我将它们作为道具传递给嵌套组件),并且一些属性需要修改状态?
编辑:现在它按照我的预期工作,但我认为更新JSON作为“道具”传递是个坏主意,它必须是更好的方式来做到这一点,但最后我保持我的状态'项目'和'小时'同步与JSON'保留'对象。
var ReservationBox = React.createClass({
getInitialState: function() {
return {
projectName: this.props.reservation.project.projectName,
hours: this.props.reservation.hours
}
},
onSelectProject: function (selectedProject) {
this.setState({projectName: selectedProject.projectName});
this.props.reservation.project = selectedProject;
},
handleHoursChange: function (e) {
this.setState({hours: e.target.value})
this.props.reservation.hours = e.target.value;
},
render: function() {
return (
<div>
<div className="btn-group timesheet-project-column">
<button type="button"
className="btn btn-primary">{this.state.projectName}</button>
<button type="button" className="btn btn-primary dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span className="caret"></span>
<span className="sr-only">Toggle Dropdown</span>
</button>
<AvailableProjectsListBox reservation={this.props.reservation}
onSelectProject={this.onSelectProject}/>
</div>
<div className="timesheet-column">
<button type="button" className="btn btn-default">
<span className="glyphicon glyphicon-pencil"/>
</button>
</div>
<div className="timesheet-column">
<input type="text" className="form-control timesheet-hour"
value={this.state.hours}
onChange={this.handleHoursChange}/>
</div>
<div className="timesheet-column">
<button type="button" className="btn btn-danger">
<span className="glyphicon glyphicon-trash img-circle text-danger"></span>
</button>
</div>
</div>
);
}
});
你能否详细说明*“这不起作用”*的意思?它会在控制台中抛出一个错误,还是只是在默默地失败? – ivarni
value = {this.state.reservation.hours} onChange = {this.handleHoursChange} />“保留默认值,即分配给我的输入字段”input type =“text”className =“form-controltimesheet-hour” 在getInitialState中。当我输入新的时候,默认会立即覆盖它。 –
你想更新数据库中的时间吗?或者你想保持本地? – jacoballenwood