2015-11-06 71 views
2

我在我的Meteor + React应用程序中有一个文本框。我想将其值同步到Mongo集合。但是,我不想在每次击键后更新集合,只有当用户停止键入几秒时才会更新集合。同步React状态到使用去抖动的Meteor集合

文本框在我render()功能如下:

<input type="text" ref="answer" onChange={this.onChange} value={this.state.someValue} /> 

我的文本框的值存储在this.state而不是this.data因为this.data反映蒙戈集合,它可能尚未更新。

到目前为止,所有这些工作。

问题:

如果另一个客户端将更新集合,我想文本框来显示更新值。为此,我必须更新getMeteorData()函数中的this.state,但这是不允许的,并且出现错误:“在getMeteorData中调用setState可能导致无限循环”

现在我有一个解决方法,我手动更新componentDidMount()getMeteorData()中的文本框值,但它感觉有点ha and,我根本不喜欢它。

有没有更好的方法来做到这一点?如果我保证我会成为一个好孩子并表现得很好,我可以在getMeteorData()的内部强制更新吗?

回答

1

我会摆脱getMeteorData在所有和转到createContainer。数据流大部分时间都变得清晰简单,包括这个特定的情况。在这里。

首先,创建一个容器来获取数据。

export default theContainer = createContainer(() => { 
    // Subscribe to the publication which publishes the data. 
    const subscription = Meteor.subscribe(...); 
    // Derive the data for the input box and form the props to pass down. 
    const props = { 
    answer: getAnswer(subscription) 
    }; 
    return props; 
}, theComponent); 

theContainer充当容器组件和由道具transferes所包含的数据的表象部件theComponent。请注意,createContainer的功能是相应的,这意味着该功能中被动数据源的更改会触发重新运行并导致重新显示theComponent

现在我们都是武装的。由于Mongo集合中的数据(正好是Minimongo)由传递的道具同步,所以theComponent通过道具转换知道同步。

export default class theComponent extends React.Component { 
    ... 

    componentWillReceiveProps(nextProps) { 
    if (this.props.answer !== nextProps.answer) { 
     this.setState({ 
     answer: nextProps.answer 
     }); 
    } 
    } 

    render() { 
    return <input value={this.state.answer} onChange={this.onChange} />; 
    } 
} 

虽然这种转变发生,即将到来的值被更新的状态,并且该控制部件将使得基于更新后的新的值的输入。

另一方面,当用户开始键入时,更改处理程序this.onChange会将用户的输入更新为每个按键的状态,因为这是受控组件。但是,处理程序只有在预设时间已过时才会更新Mongo集合(同样是Minimongo)以保存数据传输。