React + Reflux - 共享同一商店的组件的队列和超时问题

时间:2015-07-30 09:17:06

标签: reactjs refluxjs

我有一个像这样的组件,

我为这个例子重构了它,不使用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>

由于

1 个答案:

答案 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);
}

感谢