使用 ReactJs,当我从 props 发送的父对象发生变化时,如何更新我的表单字段?
Using ReactJs, How do I update my form fields when my parent object sent in from props changes?
我正在使用 REactJs 动态创建一些表单域。这些表单字段被映射到文档对象。从视觉上看,它是一个三列应用程序。左侧显示的文档队列有许多可点击的文档图标,中间是字段,右侧是文档图像。可以有多个文档。每个文档都有与之关联的字段。如果用户在字段中输入值,然后单击另一个文档。我希望为新文档或加载的保存值重置输入字段。
以下是我最后一次尝试使用 DefaultValue 属性的尝试;我试图从函数中传递值。我也尝试过 value 属性,但是它锁定了不允许用户更改它的值。
目前我已成功保存文档队列及其字段的状态,但我无法获得 UI 来反映我的状态对象:documentQueue。
我读过人们建议使用 value={state} 的地方,但这对我的状态对象不太适用。我的表单更加动态和复杂。
var Fields = React.createClass({
getInitialState: function () {
return {
currentDocumentIndex: 0,
shouldUpdate: false,
randomKey : 0
};
},
componentWillReceiveProps: function (nextProps) {
console.log("compare props");
console.log(nextProps.fields === this.props.fields);
var forceRender = !(nextProps.fields === this.props.fields);
//only change state if needed.
if (forceRender) {
if (!this.state.shouldUpdate) {
this.setState({ shouldUpdate: true ,randomKey : Math.random() }, function () {
console.log("should update fields state set");
console.log(this.state.shouldUpdate);
});
}
} else {
if (this.state.shouldUpdate) {
this.setState({ shouldUpdate: false , randomKey: Math.random() }, function () {
console.log("should update fields state set");
console.log(this.state.shouldUpdate);
});
}
}
},
getDataType: function (datatype, fieldId) {
switch (datatype) {
case 0:
case 1:
case 2:
case 3:
case 4:
return <div class="col-sm-6"><input type="text" key={this.state.randomKey+1} className="form-control" id={fieldId} onChange={this.onValueChanged.bind(this)} value={this.props.fields[fieldId]} /></div>
case 5:
return <div class="col-sm-6"><input type="text" key={this.state.randomKey+2} className="form-control" id={fieldId} onChange={this.onValueChanged.bind(this)} /></div>
case 6:
return <div class="col-sm-6"><input type="checkbox" key={this.state.randomKey+3} className="form-control" id={fieldId} value="true" onChange={this.onChecked.bind(this)} /></div>
case 7:
return <div class="col-sm-6"><textarea type="text" rows="5" key={this.state.randomKey+4} className="form-control" id={fieldId} onChange={this.onValueChanged.bind(this)} ></textarea></div>
}
},
onChecked : function(event){
},
onValueChanged : function(event){
this.props.onFieldChange(this.props.currentDocumentIndex, event.target.id, event.target.value);
},
renderFields: function () {
var fieldNames = [];
if (this.props.doctype == null) {
console.log("fields are null");
} else {
console.log("fields are valid from Field component");
for (var index = 0; index < this.props.doctype.Fields.length; index++)
{
var inputField = this.getDataType(this.props.doctype.Fields[index].DataType, this.props.doctype.Fields[index].DocumentTypeFieldID);
fieldNames.push(<label className="control-label col-sm-6">{this.props.doctype.Fields[index].Name}</label>);
fieldNames.push(inputField);
}
}
return (
<form className="form-horizontal" role="form">
<div className="form-group">
{fieldNames}
</div>
</form>
);
},
render: function () {
return (
<div>
{this.renderFields()}
</div>
);
}
});
如果你想用 React 管理一个 input
值,你可以使用 value
属性。
但是,如您所见,用户无法再直接编辑该字段。
要允许用户编辑,您还必须在该字段上设置 onChange
并将传入的编辑写在某处,例如 state
。
docs for ReactLink
有一个很好的例子:
var NoLink = React.createClass({
getInitialState: function() {
return {message: 'Hello!'};
},
handleChange: function(event) {
this.setState({message: event.target.value});
},
render: function() {
var message = this.state.message;
return <input type="text" value={message} onChange={this.handleChange} />;
}
});
此外,您可能只想使用 ReactLink
。
我正在使用 REactJs 动态创建一些表单域。这些表单字段被映射到文档对象。从视觉上看,它是一个三列应用程序。左侧显示的文档队列有许多可点击的文档图标,中间是字段,右侧是文档图像。可以有多个文档。每个文档都有与之关联的字段。如果用户在字段中输入值,然后单击另一个文档。我希望为新文档或加载的保存值重置输入字段。
以下是我最后一次尝试使用 DefaultValue 属性的尝试;我试图从函数中传递值。我也尝试过 value 属性,但是它锁定了不允许用户更改它的值。
目前我已成功保存文档队列及其字段的状态,但我无法获得 UI 来反映我的状态对象:documentQueue。
我读过人们建议使用 value={state} 的地方,但这对我的状态对象不太适用。我的表单更加动态和复杂。
var Fields = React.createClass({
getInitialState: function () {
return {
currentDocumentIndex: 0,
shouldUpdate: false,
randomKey : 0
};
},
componentWillReceiveProps: function (nextProps) {
console.log("compare props");
console.log(nextProps.fields === this.props.fields);
var forceRender = !(nextProps.fields === this.props.fields);
//only change state if needed.
if (forceRender) {
if (!this.state.shouldUpdate) {
this.setState({ shouldUpdate: true ,randomKey : Math.random() }, function () {
console.log("should update fields state set");
console.log(this.state.shouldUpdate);
});
}
} else {
if (this.state.shouldUpdate) {
this.setState({ shouldUpdate: false , randomKey: Math.random() }, function () {
console.log("should update fields state set");
console.log(this.state.shouldUpdate);
});
}
}
},
getDataType: function (datatype, fieldId) {
switch (datatype) {
case 0:
case 1:
case 2:
case 3:
case 4:
return <div class="col-sm-6"><input type="text" key={this.state.randomKey+1} className="form-control" id={fieldId} onChange={this.onValueChanged.bind(this)} value={this.props.fields[fieldId]} /></div>
case 5:
return <div class="col-sm-6"><input type="text" key={this.state.randomKey+2} className="form-control" id={fieldId} onChange={this.onValueChanged.bind(this)} /></div>
case 6:
return <div class="col-sm-6"><input type="checkbox" key={this.state.randomKey+3} className="form-control" id={fieldId} value="true" onChange={this.onChecked.bind(this)} /></div>
case 7:
return <div class="col-sm-6"><textarea type="text" rows="5" key={this.state.randomKey+4} className="form-control" id={fieldId} onChange={this.onValueChanged.bind(this)} ></textarea></div>
}
},
onChecked : function(event){
},
onValueChanged : function(event){
this.props.onFieldChange(this.props.currentDocumentIndex, event.target.id, event.target.value);
},
renderFields: function () {
var fieldNames = [];
if (this.props.doctype == null) {
console.log("fields are null");
} else {
console.log("fields are valid from Field component");
for (var index = 0; index < this.props.doctype.Fields.length; index++)
{
var inputField = this.getDataType(this.props.doctype.Fields[index].DataType, this.props.doctype.Fields[index].DocumentTypeFieldID);
fieldNames.push(<label className="control-label col-sm-6">{this.props.doctype.Fields[index].Name}</label>);
fieldNames.push(inputField);
}
}
return (
<form className="form-horizontal" role="form">
<div className="form-group">
{fieldNames}
</div>
</form>
);
},
render: function () {
return (
<div>
{this.renderFields()}
</div>
);
}
});
如果你想用 React 管理一个 input
值,你可以使用 value
属性。
但是,如您所见,用户无法再直接编辑该字段。
要允许用户编辑,您还必须在该字段上设置 onChange
并将传入的编辑写在某处,例如 state
。
docs for ReactLink
有一个很好的例子:
var NoLink = React.createClass({
getInitialState: function() {
return {message: 'Hello!'};
},
handleChange: function(event) {
this.setState({message: event.target.value});
},
render: function() {
var message = this.state.message;
return <input type="text" value={message} onChange={this.handleChange} />;
}
});
此外,您可能只想使用 ReactLink
。