在redux中限制调度产生奇怪的行为

时间:2015-12-14 19:24:42

标签: reactjs redux

我有这堂课:

export default class Search extends Component {

    throttle(fn, threshhold, scope) {
       var last,
           deferTimer;
       return function () {
            var context = scope || this;
            var now = +new Date,
           args = arguments;
           if (last && now < last + threshhold) {
            // hold on to it
               clearTimeout(deferTimer);
               deferTimer = setTimeout(function () {
                   last = now;
                   fn.apply(context, args);
               }, threshhold);
           } else {
               last = now;
               fn.apply(context, args);
           }
       }
    }

    render() {
        return (
          <div>
            <input type='text' ref='input' onChange={this.throttle(this.handleSearch,3000,this)} />
          </div>
        )
    }

    handleSearch(e) {
        let  text = this.refs.input.value;
        this.someFunc();
        //this.props.onSearch(text)
    } 

    someFunc() {
        console.log('hi')
    }
}

所有这些代码都会每隔3秒注销hi - throttle调用handleSearch方法来处理此问题

一旦我取消注释这一行:

this.props.onSearch(text)

限制方法停止生效,控制台只有在没有暂停的情况下按下键时才会注销hi,并且还会调用oSearch函数。

onSearch方法是从主应用程序传递的prop方法:

<Search onSearch={ text => dispatch(search(text)) } /> 

redux dispatch会触发redux搜索操作,如下所示:

export function searchPerformed(search) {
    return {
        type: SEARCH_PERFORMED
    }
}

我不知道为什么会发生这种情况 - 我猜测它与redux有关,因为当handleSearch调用onSearch时会出现问题,而onSearch会在父组件中触发redux dispatch。

3 个答案:

答案 0 :(得分:1)

问题是它第一次执行时会转到else,它会调用dispatch函数。减速器可能会立即更新某些状态,并导致重新渲染;重新渲染会导致输入再次创建,并带有一个新的节流闭合&#39;这又是空的&#39; last&#39;和&#39; deferTimer&#39; - &GT;每次都去其他地方,因此立即更新。

答案 1 :(得分:1)

正如迈克指出的那样,如果组件不需要更新,那么只是不更新​​组件就可以获得正确的行为。

在我的情况下,我有一个组件需要每隔几秒轮询一次服务器以获取更新,直到一些状态派生的prop改变了值(例如&#39; pending&#39; vs&#39; complete&#39; ;)

每次新数据进入时,组件都会重新渲染,并再次调用动作创建者,并限制动作创建者无法正常工作。

我只需将相关的动作创建者交给组件挂载的setInterval即可解决。是的,它是渲染上发生的副作用,但它很容易推理,实际的状态变化仍然通过调度员。

如果您想保持纯净,或者您的使用案例更复杂,请查看https://github.com/pirosikick/redux-throttle-actions

答案 2 :(得分:0)

感谢luanped帮我解决了这个问题。有了这个,我就能找到一个简单的解决方案。搜索组件不需要更新,因为输入是不受控制的组件。为了解决我遇到的周期性问题,我已经使用了shouldComponentUpdate来阻止它重新渲染:

NULL

我还把油门移到了构造函数中,因此只能有一次油门实例。

我认为这是一个很好的解决方案,但我只是刚刚开始学习反应,所以如果有人能指出这种方法的问题,那将是受欢迎的。