为什么 ReactClass 中的反应函数会在表单输入更改事件中重复调用
Why does react function in ReactClass get called repeatedly on form input change events
我有一个 react-bootstrap React Class,其中 createList 函数在表单输入(workDone 或 hoursAndMinutes)的每个键输入上被调用。我是 reactjs 的新手,也许这是正常行为,但在我看来并非如此,因此我做错了什么。
var SubjectBox = React.createClass({
getInitialState(){
return({
totalHoursAndMinute:0,
subject:'',
workDone:'',
hoursAndMinutes:'',
})
},
dropDownSelected:function(e){
this.setState({subject:e.target.value})
},
handleChangeToWorkDone(){
let s = this.refs.workDone.getValue();
console.log(s);
this.setState({
workDone: s
});
},
validateWorkDone:function(){
let length = this.state.workDone.length;
if (length >= 10) return 'success';
else if (length > 5) return 'warning';
else if (length > 0) return 'error';
},
validateHoursAndMinutes(){
let hm = this.state.hoursAndMinutes.split(':');
if (hm.length === 2){
return 'success';
}else{
return 'error';
}
},
handleChangeToHoursMinute(){
var minutes =0;
let s =this.refs.hoursAndMinutes.getValue();
let hm = s.split(':');
if (hm.length===2){
var h = parseInt(hm[0].trim());
var m = parseInt(hm[1].trim());
if (!m.isNaN){
var minutes = h*60+m;
}
}
this.setState({
hoursAndMinutes: s,
totalMinutes:minutes
});
},
createList: function(){
console.log("create list function.");
var list=[];
for (var i = 0; i < this.props.subjects.length;i++){
list.push(<option key={i} value={this.props.subjects[i].subject}>{this.props.subjects[i].subject}</option>)
}
return list;
},
handleSubmit: function(e){
e.preventDefault();
console.log(this.state.workDone);
console.log(this.state.subject);
},
render(){
return(
<form onSubmit={this.handleSubmit}>
<Input ref="subjectList" type="select" label="Subject" onChange={this.dropDownSelected}>
{this.createList()}
</Input>
<Input ref="workDone"
type="text"
value={this.state.workDone}
placeholder="What did you do?"
label="What did you do" help="Input is 10 or more characters."
bsStyle={this.validateWorkDone()} hasFeedback
groupClassName="group-class" labelClassName="label-class"
onChange={this.handleChangeToWorkDone} />
<Input ref="hoursAndMinutes"
type="text" value={this.state.hoursAndMinutes} placeholder="HH:MM?"
label="How long did you do it?" help="Input in hours:minutes, example 1:5 = an hour and five minutes."
bsStyle={this.validateHoursAndMinutes()} hasFeedback
groupClassName="group-class"
labelClassName="label-class" onChange={this.handleChangeToHoursMinute} />
<Button type="submit" bsStyle="success">Submit</Button>
</form>
)
}
});
发生这种情况是因为您在 handleChangeToWorkDone
和 handleChangeToWorkDone
setState
中使用调用 re-render
setState()
will always trigger a re-render unless conditional
rendering logic is implemented in shouldComponentUpdate()
. If mutable
objects are being used and the logic cannot be implemented in
shouldComponentUpdate()
, calling setState()
only when the new state
differs from the previous state will avoid unnecessary re-renders.
在 React Js 中,HTML/DOM 始终只是对 React 组件状态的表示。
每当有 onChange 或 onBlur 或任何事件发生时,如果 React 组件的状态发生变化(使用 setState 函数),ReactJs 组件将被重新渲染(使用 Render 函数)。
只有当 React Js 组件的状态发生变化时,您的 UI 才能更新为您输入的值。因此,这是 React Js 中的预期行为。
我有一个 react-bootstrap React Class,其中 createList 函数在表单输入(workDone 或 hoursAndMinutes)的每个键输入上被调用。我是 reactjs 的新手,也许这是正常行为,但在我看来并非如此,因此我做错了什么。
var SubjectBox = React.createClass({
getInitialState(){
return({
totalHoursAndMinute:0,
subject:'',
workDone:'',
hoursAndMinutes:'',
})
},
dropDownSelected:function(e){
this.setState({subject:e.target.value})
},
handleChangeToWorkDone(){
let s = this.refs.workDone.getValue();
console.log(s);
this.setState({
workDone: s
});
},
validateWorkDone:function(){
let length = this.state.workDone.length;
if (length >= 10) return 'success';
else if (length > 5) return 'warning';
else if (length > 0) return 'error';
},
validateHoursAndMinutes(){
let hm = this.state.hoursAndMinutes.split(':');
if (hm.length === 2){
return 'success';
}else{
return 'error';
}
},
handleChangeToHoursMinute(){
var minutes =0;
let s =this.refs.hoursAndMinutes.getValue();
let hm = s.split(':');
if (hm.length===2){
var h = parseInt(hm[0].trim());
var m = parseInt(hm[1].trim());
if (!m.isNaN){
var minutes = h*60+m;
}
}
this.setState({
hoursAndMinutes: s,
totalMinutes:minutes
});
},
createList: function(){
console.log("create list function.");
var list=[];
for (var i = 0; i < this.props.subjects.length;i++){
list.push(<option key={i} value={this.props.subjects[i].subject}>{this.props.subjects[i].subject}</option>)
}
return list;
},
handleSubmit: function(e){
e.preventDefault();
console.log(this.state.workDone);
console.log(this.state.subject);
},
render(){
return(
<form onSubmit={this.handleSubmit}>
<Input ref="subjectList" type="select" label="Subject" onChange={this.dropDownSelected}>
{this.createList()}
</Input>
<Input ref="workDone"
type="text"
value={this.state.workDone}
placeholder="What did you do?"
label="What did you do" help="Input is 10 or more characters."
bsStyle={this.validateWorkDone()} hasFeedback
groupClassName="group-class" labelClassName="label-class"
onChange={this.handleChangeToWorkDone} />
<Input ref="hoursAndMinutes"
type="text" value={this.state.hoursAndMinutes} placeholder="HH:MM?"
label="How long did you do it?" help="Input in hours:minutes, example 1:5 = an hour and five minutes."
bsStyle={this.validateHoursAndMinutes()} hasFeedback
groupClassName="group-class"
labelClassName="label-class" onChange={this.handleChangeToHoursMinute} />
<Button type="submit" bsStyle="success">Submit</Button>
</form>
)
}
});
发生这种情况是因为您在 handleChangeToWorkDone
和 handleChangeToWorkDone
setState
中使用调用 re-render
setState()
will always trigger a re-render unless conditional rendering logic is implemented inshouldComponentUpdate()
. If mutable objects are being used and the logic cannot be implemented inshouldComponentUpdate()
, callingsetState()
only when the new state differs from the previous state will avoid unnecessary re-renders.
在 React Js 中,HTML/DOM 始终只是对 React 组件状态的表示。
每当有 onChange 或 onBlur 或任何事件发生时,如果 React 组件的状态发生变化(使用 setState 函数),ReactJs 组件将被重新渲染(使用 Render 函数)。
只有当 React Js 组件的状态发生变化时,您的 UI 才能更新为您输入的值。因此,这是 React Js 中的预期行为。