这里我有一个表单组件,其中有一个角色和子角色组件。角色组件工作正常,但是当我添加子角色组件时,当渲染函数运行时,this.props.roleList将是未定义的。如果我在渲染期间不在子角色组件中迭代this.props.roleList,只是让它成为,我可以看到道具实际上是正确的。怎么会这样?
//The form itself, this is the component which contains state.
var SupplierForm = React.createClass({
loadSupplierTemplateFromServer: function() {
$.ajax({
url: this.props.getSupplierTemplateUrl,
dataType: 'json',
cache: true,
success: function(data) {
this.setState({ supplierTemplate: data });
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.getSupplierTemplateUrl, status, err.toString());
}.bind(this)
});
},
handleSupplierSubmit: function(e) {
e.preventDefault();
$.ajax({
url: this.props.registerSupplierUrl,
dataType: 'json',
type: 'POST',
data: this.state.supplier,
success: function() {
//TODO: What now after supplier is registered?
}.bind(this),
error: function(xhr, status, err) {
//TODO: In case of errors, guide the user onwards based on type of error
console.error(this.props.registerSupplierUrl, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {
roleSelected: "Choose a role",
subRoleSelected: "",
supplierTemplate: []
};
},
componentDidMount: function() {
this.loadSupplierTemplateFromServer();
},
updateState: function(stateObject) {
this.setState(stateObject);
},
render: function () {
return (
<div className="supplierForm">
<form>
<h4 className="col-md-6 bifrost-formpart-header">Basic information</h4>
<div className="container col-md-6 bifrost-col-centered-top">
<BasicInformation basicInfo={this.state.supplierTemplate["Basic Information"]}
updateState={this.updateState} />
</div>
<h4 className="col-md-6 bifrost-formpart-header">What is your occupation?</h4>
<div className="container col-md-6 bifrost-col-centered-bottom">
<Roles updateState={this.updateState}
roleList={this.state.supplierTemplate["_supplierTypes"]}
selectedRole={this.state.roleSelected}></Roles>
</div>
<h4 className="col-md-6 bifrost-formpart-header">What is your occupation?</h4>
<div className="container col-md-6 bifrost-col-centered-bottom">
<Subroles updateState={this.updateState}
roleList={this.state.supplierTemplate["_supplierTypes"]}
selectedRole={this.state.roleSelected}></Subroles>
</div>
</form>
</div>
);
}
});
//Basic information part of the form
var BasicInformation = React.createClass({
handleBasicInfoChange: function(event) {
var stateObject = function () {
var returnObj = {};
returnObj[event.target.name] = event.target.value;
return returnObj;
}.bind(event);
this.props.updateState(stateObject);
},
render: function () {
var fields = [];
var keyCounter = 0;
var keyName = "";
for (var basickey in this.props.basicInfo) {
if (this.props.basicInfo.hasOwnProperty(basickey)) {
keyCounter = keyCounter + 1;
keyName = "basic" + keyCounter;
fields.push(
<input type={this.props.basicInfo[basickey]}
placeholder={basickey}
name={basickey}
onChange={this.handleBasicInfoChange}
className="form-control"
key={keyName}/>
);
}
}
return (
<div className="list-group">{fields}
</div>
);
}
});
var Roles = React.createClass({
handleRoleSelection: function (event) {
event.preventDefault();
var stateObject = function () {
var returnObj = {};
returnObj["roleSelected"] = event.target.textContent;
return returnObj;
}.bind(event);
this.props.updateState(stateObject);
},
render: function () {
var roles = [];
var keyCounter = 0;
var keyName = "";
for (var rolekey in this.props.roleList) {
if (this.props.roleList.hasOwnProperty(rolekey)) {
keyCounter = keyCounter + 1;
keyName = "role" + keyCounter;
roles.push(
<li><a href="#" onClick={this.handleRoleSelection} key={keyName}>{rolekey}</a></li>
);
}
}
return (
<div className="input-group">
<div className="dropdown">
<button className="btn btn-default dropdown-toggle bifrost-dropdown-button" type="button" id="rolesDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">{this.props.selectedRole}
<span className="caret"></span>
</button>
<ul className="dropdown-menu" aria-labelledby="rolesDropdown">{roles}
</ul>
</div>
</div>
);
}
});
var Subroles = React.createClass({
componentDidMount: function () {
console.log(this.props.roleList);
},
handleSubRoleSelection: function(event) {
event.preventDefault();
var stateObject = function () {
var returnObj = {};
returnObj["subRoleSelected"] = event.target.textContent;
return returnObj;
}.bind(event);
this.props.updateState(stateObject);
},
render: function () {
var subroles = [];
var keyCounter = 0;
var keyName = "";
for (var subkey in this.props.roleList["_supplierTypes"]["Photography"]["_supplierSubTypes"]) {
if (this.props.roleList["_supplierTypes"]["Photography"]["_supplierSubTypes"][subkey].hasOwnProperty(subkey)) {
keyCounter = keyCounter + 1;
keyName = "subrole" + keyCounter;
subroles.push(
<button type="button" className="btn-sm btn-default col-md-5 bifrost-button" onClick={this.handleSubRoleSelection} key={keyName}>{subkey}</button>
);
}
}
return (
<div className="btn-group btn-group-justified">{subroles}
</div>
);
}
});
var Fields = React.createClass({
render: function () {
return (
<div className="input-group">
</div>
);
}
});
ReactDOM.render(
<SupplierForm getSupplierTemplateUrl="/api/suppliers/GetSuppliersTemplate"
registerSupplierUrl="/Account/RegisterSupplier" />, document.getElementById('content')
);