我有一个像这样的组件,
我为这个例子重构了它,不使用valueLink来帮助说明问题。
在这个例子中,我有一个Field组件,多次渲染(3)都绑定到商店中的同一属性。这个概念非常简单,当输入改变为一个时,它将反映在其他的中。
如果您输入的速度非常快(bash中的几个键),并且事件排队,则结束于一个循环,其中每个组件都根据另一个组件的早期状态更新进行更新。如果你输入的速度很慢,我觉得队列上的滴答超时更慢,它运行正常。
使用值链接可以观察到类似的症状。但它正在做同样的事情,所以我希望如此。
var App = React.createClass({
render: function() {
return <Field dataItemName="PropertyA" />
<Field dataItemName="PropertyA" />
<Field dataItemName="PropertyA" />;
}
});
var RecordStore = Reflux.createStore({
mixins: [StateMixin],
listenables: [FormActions, RecordActions],
init: function () {
},
getInitialState: function () {
return { PropertyA : 'test' };
},
valueChanged: function (newVal, propName) {
var o = {};
if (newVal !== this.state[propName].value) {
o[propName] = newVal;
this.setState(o);
}
}
});
var Field = React.createClass({
mixins: [Reflux.ListenerMixin],
getInitialState: function () {
return ({
value: RecordStore.state[this.props.dataItemName].value
})
},
componentDidMount: function(){
this.listenTo(RecordStore[this.props.dataItemName], this.updateValue);
},
updateValue: function (value) {
this.setState({ value: value.value });
},
shouldComponentUpdate: function (nextProps, nextState) {
return nextState.value != this.state.value;
},
componentDidUpdate: function (prevProps, prevState) {
RecordActions.valueChanged(this.state.value, this.props.dataItemName);
},
handleInput: function (event) {
this.setState({ value: event.target.value });
},
render: function () {
return (
<div className='form-group'>
<label htmlFor={this._reactInternalInstance._rootNodeID+'_input'}>{this.props.label}</label>
<input className="form-control" value={this.state.value} id={this._reactInternalInstance._rootNodeID+'_input'} onChange={this.handleInput} />
</div>
);
}
});
我想过在更新商店中的值之前使用我自己的超时,即等到用户完成输入;但我想知道框架/ lib中是否有任何东西可以处理它?</ p>
由于
答案 0 :(得分:0)
好的,所以这里是任何寻找使用超时解决方案的人的答案。
问题可以追溯到React的drainQueue,它调用队列中的其余项目。在这个解决方案中,我只想推迟将updateValue放在队列中,直到我们确定通过抨击键盘创建的事件的速度已经完成。
通过更改componentDidUpdate
以使用超时(我认为它只需要> 0)意味着每次按键都不会触发事件,从而否定我最初询问的问题。
componentDidUpdate: function (prevProps, prevState) {
**var _self = this;
clearTimeout(_self.state.inputtimer);
_self.state.inputtimer = setTimeout(function () { RecordActions.valueChanged(_self.state.value, _self.props.dataItemName);},50);**
}
这似乎完成了这项工作。任何评论或其他解决方案都非常受欢迎。我更喜欢使用valueLink(我认为我仍然可以想到)完成它,并且我可以为超时创建一个mixin。
这是drainQueue函数供参考。
function drainQueue() {
if (draining) {
return;
}
var timeout = setTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
currentQueue[queueIndex].run();
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
clearTimeout(timeout);
}
感谢